Newsgroup: it.comp.os.linux.iniziare
Titolo: eseguire riga di comando all'interno di uno script bash

ho creato il file test.sh in cui ci sono le seguenti istruzioni:
 
!/bin/bash
// [esecuzione comando]
echo "Abbiamo finito"
 
Se adesso digito
 
test.sh cp -i 123 abc
 
viene visualizzato: Abbiamo finito
 
Ma io vorrei che prima di ciï¿œ venga anche eseguito il comando
 
cp -i 123 abc
 
Quindi al posto di [esecuzione comando] quale istruzione ci dovrei mettere?

 ... 
 
man shift
man exec
man eval
 
e poichè sono comandi interni
 
man bash
 
 

 mettere?
 
eval "$*"
 
 

 La shell usa # per i commenti
 
giusto


 
grazie

 eval "$*"
 
Due errori (vabbè uno e mezzo) in una solo riga. E meno male che 
sono solo nove caratteri.
 
Primo "$*" va usato solo se si sa cosa si sta facendo, negli altri casi
meglio usare "$@"
 
Secondo meglio usare  exec al posto di eval specie se si sta tentando 
di fare un wrapper.
 
 
 
 


ok ;)

 fare un wrapper.
 
Ma anche no.
exec termina lo script principale, visto che dopo ha messo delle 
istruzioni è evidente non sia ciò che vuole.
Per il resto mi sembra di notare una immotivata spocchia.
 

 Quindi al posto di [esecuzione comando] quale istruzione ci dovrei mettere?
 
`$1`
ed esegui digitando
$ ./test.sh "cp -i 123 abc"
 

 eval "$*"
 
Toglimi una curiosita` che non ha mai capito.
 
Perche`:
 
eval "$*"
 
Invece di:
 
"$*"
 
e basta?
 
bye,
 
-- 
 
piergiorgio

 e basta?
 
Nessun motivo particolare. Sono consapevole che il risultato è lo stesso.
 

Addi' 07 ott 2014, Lo gnomo armato di ascia scrive:

Sapete dove c'era sempre? nel profile della Slack, se lo usa Volkerding
ci avra' i suoi buoni motivi.
 
Comunque se metti nel file COMANDO queste tre righe:
------
echo
ls /tmp
echo
---------
 
e se poi dai:
$(cat COMANDO)
 
oppure se dai:
eval $(cat COMANDO)
 
ti stampa semplicemente: "ls /tmp echo", in entrambi i casi.
 
Pero' se invece cambi COMANDO cosi':
------
echo;
ls /tmp;
echo
---------
 
allora
$(cat COMANDO)
ti da' errore, mentre invece
eval $(cat COMANDO)
finalmente esegue i tre comandi in successione, come volevi.
 
-- 
Tanti saluti
 


  In sostanza dipende da quello che si vuole fare e da come sono i parametri
sulla riga di comando.  Se i parametri dati sulla riga di comando contengono
delle direttive di espansione di variabile che si vuole siano espanse prima
che la riga sia eseguita nello script, allora va usato eval.  Se invece si
vuole che siano passate così come sono, allora direttamente "$@".
 
  Ad esempio:
 
$ cat /tmp/a
#!/bin/bash
echo Prova
"$@"
echo fine
 
$ /tmp/a echo \$SHELL
Prova
$SHELL
fine
 
$ cat /tmp/b
#!/bin/bash
echo Prova
eval "$@"
echo fine
 
$ /tmp/b echo \$SHELL
Prova
/bin/bash
fine
 
 
  Ciao,
 
 
-- 
Alessandro Selli 
http://alessandro.route-add.net
 
AVVERTENZA: i messaggi inviati a "trappola" non mi arriveranno.
WARNING: messages sent to "trappola" will never reach me.

Il 07/10/2014 12:51, mallin.shetland ha scritto:

ma così mi chiude il terminale in modo fraudolento :-|
 

 meglio usare "$@"
 
chiedo scusa ma non ho capito la differenza.
Si ho cercato su internet, ma tutto inglese... :-P


Il che dovrebbe suggerirti quanto importante
sia imparare quella lingua... :-P
 
La linea di comando *completa* passata ad uno
script viene rappresentata, credo, dalle seguenti
variabili: $*, $@, "$*", "$@".
 
Che hanno 4 (o 3) significati diversi.
 
$* sono tutti gli elementi sulla linea di comando,
separati da spazi, indipendentemente dalle virgolette.
 
Quindi:
 
1) script.sh a b c ha, in $*, 3 valori
2) script.sh a "b c", ha sempre 3 valori
 
Se si usa "$*", allora si ha *sempre* un valore
solo, cioe` "a b c".
 
L'uso corretto e` "$@", che riporta *esattamente*
la linea di comando.
 
Quindi, 1) ha 3 valori e 2) ha 2 valori.
 
Questo serve, ovviamente, qualora si chiami un
altro eseguibile con la stessa linea di comando.
 
Se lo script.sh e` fatto semplicemente cosi`:
 
#!/bin/bash
 
cp "$@"
cp "$*"
cp $*
cp $@ # questa non la ricordo
 
Allora solo la prima funziona come dovrebbe,
assumendo si dia qualcosa cosa:
 
script.sh "nome file.fil" "nome copia.fil"
 
"$@" e` corretto: "nome file.fil" "nome copia.fil"
"$*" e` "nome file.fil nome copia.fil"
$* e` "nome" "file.fil" "nome" "copia.fil"
$@, come scrivevo sopra, non ricordo...
 
bye,
 
-- 
 
piergiorgio

 fine
 
 
Ah! Ecco!
 
Grazie dell'esempio, mi hai chiarito la differenza.
 
bye,
 
-- 
 
piergiorgio

 istruzioni è evidente non sia ciò che vuole.
 
A me è evidente che vuole fare esperienza ed imparare ad usare
la shell, per cui fornisco informazioni corrette basate sulla mie 
esperienza e sottolineo la pericolosità di costrutti del cazzo come
eval che servono solo a fare danni.
 
--
eval is a mispellig for evil

 vuole che siano passate così come sono, allora direttamente "$@".
 
Guarda che è esattamente il contrario: se  il comando deve essere 
espanso allora usa "$@". Se invece sei sicuro che non avverrà in 
nessun modo una espansione usa eval.
 
Il problema con eval è proprio che il comando viene espanso due volte.
 
PS a proposito "$@" rimane un modo stupido per eseguire un comando 
poiché non viene eseguito nessun controllo sugli argomenti passati. 
Non dico che non vada bene ma bisogna essere sicuri di ciò che si 
sta facendo e fare comunque un controllo preventivo sugli argomenti.

 Nessun motivo particolare. Sono consapevole che il risultato è lo stesso.
 
No, non è lo stesso (vedi Piergiorgio Sartor e seguenti)
 

 ci avra' i suoi buoni motivi.
 
ATTENZIONE Il fatto che una cosa venga usata in uno programma nel 
mondo reale non è detto che sia una cosa buona e giusta. Hai presente
i programmatori che ci sono in giro? Shellshock non ti dice niente? 
 
http://mywiki.wooledge.org/ShellHallOfShame/Page2
 
 
 

 ma così mi chiude il terminale in modo fraudolento :-|
 
Dipende da cosa devi fare. Se vuoi fare un wrapper usa exec, 
se vuoi aggiungere funzionalità al comando usa exec, se vuoi 
fare altre cose usa:
 
/path/nomecomando "$@" 
 
 
 


http://www.pluto.it/files/ildp/guide/abs/variables2.html#APPREF
 
gli esempi sono chiarificatori.
 


voglio fare una cosa tipo questa
 
# comandi iniziali
#...
<comando_specificato>
# comandi finali
...
 
dove <comando_specificato> sarebbe ad es. "cp -i 1 2"
 
Insomma avete presente "sudo" (tutti lo conosciamo benissimo):
 
sudo cp -i 1 2
 
ecco io vorrei fare la stessa cosa con "mio_script.sh"
 
mio_script.sh cp -i 1 2
 
In pratica vorrei capire cosa usa 'sudo' al suo interno:
"$@" ?
eval "$@" ?
O qualcos'altro ?


Se vuoi occuparti di didattica invece che rispondere alle domande puntuali 
va bene, però a quel punto ti prendi la briga di spiegare, ad esempio, 
perché eval è un "costrutto del cazzo". Aspettiamo con ansia le 
argomentazioni.
 

 Quindi, 1) ha 3 valori e 2) ha 2 valori.
 
function testPars {
 
	local array=($1)
 
	echo "Numero elementi: ${#array[@]}"
 
	local i
 
	for i in ${array[@]}; do
		echo "Singolo elemento dell'array: $i"
	done
 
}
 
array=("x 1" "y" "z")
 
testPars "${array[@]}" "a" "b"
 
 
Perchè allora "x 1" non resta unito?
Inoltre se faccio
 
testPars ${array[@]} "a" "b"
 
l'"1" viene escluso del tutto

 solo, cioe` "a b c".
 
Penso dipenda dall'IFS, se faccio:
----------
IFS=\;
echo a "b c"
------------
 
quando do
$: ./script.sh a "b c"
 
mi viene:
a;b c
 
-- 
Tanti saluti
 

 Penso dipenda dall'IFS, 
 
No, IFS viene tirato in ballo poichè gli argomenti sono separati 
dall'IFS ma le regole con cui vengono separati gli argomenti non 
dipende dall' IFS. Nel manuale è spiegato per filo e per segno.
 
 

 dove <comando_specificato> sarebbe ad es. "cp -i 1 2"
 
Già ti hanno risposto "$@" ed io già ti ho detto che è una cattiva idea
 
 

 perché eval è un "costrutto del cazzo"
 
Già ho postato il link, leggi tutto il thread.

 Perché non lo chiedi direttamente?
 
a chi?
o_O
 
 

 O qualcos'altro ?
 
Direi "qualcos'altro". 'sudo' non è uno script bash. 


Cosa c'entra questo esempio con la linea di comando?
 
Per esempio, sei sicuro che le stesse regole valgano
per le funzioni?
 
bye,
 
-- 
 
piergiorgio

 per le funzioni?
 
pensavo fosse un po' la stessa cosa, pardon :-P

 a chi?
 
Stai su USENET o tra le nuvole?
 
PS Stavo per dire /cloud/

 Stai su USENET o tra le nuvole?
 
dovrei aprire un 3d apposito?
Comunque faccio fatica a capirvi: gergo esasperato, punteggiatura quasi 
assente, forme mozze...

 Guarda che è esattamente il contrario:
 
  Se non sai neanche capire gli esempi riportati non so che farci... forse
un disegnino?  Quand'è che \$SHELL rimane proprio $SHELL, quando si usa eval
o quando non lo si usa?


 assente, forme mozze...
 
Io lo lascerei perdere. Tanto risposte non ne darà mai, non ce la può fare.


  Lui è fatto così, non te la prendere, non è colpa sua.


 cp $@ # questa non la ricordo
 
  Senza doppi apici $* e $@ sono uguali.



'scolta, io ho risposto a *quella* domanda e sempre a *quella* domanda 
continuo a riferirmi. Non me ne frega nulla se in altre condizioni le cose 
sono diverse perché queste altre condizioni non sono oggetto della 
domanda. 

    Lui è fatto così, non te la prendere, non è colpa sua.
 
Comunque andateci (chi è ancora in età) qualche giorno a scuola, che 
male non fa.
A miei tempi spaccaavano sulle gengive se non imparavi ad esprimerti 
come si deve.

 eval o quando non lo si usa?
 
Che c'entra? Però qui ho sbagliato io perché non sono stato troppo chiaro.
Con "$@" l'espansione dei parametri e soprattutto la divisione in parole 
avvengono in modo pulito e sicuro, è stato introdotto proprio per questo.
Purtroppo i parametri non vengono espansi ulteriormente ed è proprio questo
il motivo che lo rende sicuro rispetto ad eval; non permette trucchi.
 
Viceversa eval è pericoloso proprio perché espande i parametri due volte, 
rendendo di fatto impossibile controllare gli argomenti passati, offrendo 
spazio a trucchi utili (ma realizzabili in modo pulito con altri strumenti 
della stessa bash o dell korn shell) ma contemporaneamente offre spazio 
a bug pericolosi o a falle della sicurezza,
 
In definitiva è abbastanza sicuro usare eval se si sono validati i parametri 
passati e se si è relativamente sicuri che non verranno ulteriormente 
espansi da eval, proprio il contrario da te affermato.
 
 
 

 proprio il contrario da te affermato.
 
  LOL, me lo citeresti, per favore?


 LOL, me lo citeresti, per favore?
 
Sempre su 
wooledge.com
:
 
http://mywiki.wooledge.org/ShellHallOfShame/Page2
 
http://mywiki.wooledge.org/BashFAQ/092
 
http://mywiki.wooledge.org/BashFAQ/048
 
 
Ed ora ti assegno il premio Sordi.
http://www.youtube.com/watch?v=VrOLHeO0M8g
 
 
--- news://
freenews.netfront.net/
 - complaints: 
ne...@netfront.net
 ---

 
http://mywiki.wooledge.org/BashFAQ/048
 
 
  A frescone, citami dove avrei scritto che eval fa il contrario del leggere
ed effettuare sostituzioni di variabile (e di comando e di espansione ecc.)
due volte sulla stessa linea di comando.


 [un sacco ed una sporta di mstronzate di cane]
 
Se non lo hai capito ti ho mandato affanculo. Non sarebbe necessario
ribadirlo (proprio perché ti ho mandato affanculo) ma visto io ho detto
che NON È OPPORTUNO PERMETTE CHE GLI ARGOMENTI DI EVAL VENGANO ESPANSI,
che ho mandato link che ribadiscono questo, che dimostrano come il
comando eval sia pericoloso e nonostante ciò tu continui ad attribuirmi 
cose che non ho detto o pensato di dire, deduco che tu sei un coglione
che non sa leggere. perchiò ripeto per la terza voleta: 
 
VA AFFANCULO!

 Quindi al posto di [esecuzione comando] quale istruzione ci dovrei mettere?
Non ho tempo di leggere tutto il thread, al netto di cazzate, come hai 
risolto? In forma estesa per piacere perchè ne so meno di te :)
 
grazie e buon linux


come già detto è una tecnica da evitare (da quanto ho capito), quindi se 
posso la evito.
Si anch'io non posso star dietro a discussioni troppo prolisse e piene 
di pareri divergenti