' è un errore di ' durante il tentativo di passare il nome della directory alla funzione

Nel mio script bash, utilizzo find per ottenere i nomi delle cartelle con caratteri jolly:

for i in $(find ${directory} -mindepth 1 -type d -name ${wildcard}); do stuff=doStuff ${i} done doStuff() { echo ${1} return ${1}"/hello"; } 

Il problema è che quando lo faccio, ottengo il seguente errore (diciamo che $ {i} corrisponde a “home / me / my_directory”):

line 111: "/home/me/my_directory": is a directory. 

(la riga 111 è la riga con “doStuff “)

Ho” provato a farlo, inutilmente:

for i in $(find ${directory} -mindepth 1 -type d -name ${wildcard}); do stuff=doStuff "${i}" done 

Apparentemente è perché il programma sta cercando di eseguire il directory, ma lo voglio solo come una stringa che posso manipolare.

Commenti

  • Hmmm …. Secondo la pagina man di bash. … Il comando integrato return in bash viene utilizzato per restituire un codice EXIT (intero) e non un qualsiasi tipo di parametro stringa.
  • Puoi anche provare find "${directory}" -mindepth 1 -type d -name "${wildcard}" -print0 | xargs -0 doStuff
  • googler : unaltra grande fonte per ricevere questo messaggio di errore ge è //a wrong bash line comment invece di #a correct bash line comment

Risposta

Le virgolette e la sostituzione dei comandi sono i tuoi problemi qui.

Il problema specifico che stai riscontrando è perché la shell sta cercando di eseguire un comando chiamato /home/me/my_directory con la variabile di ambiente stuff=doStuff.
Quello che vuoi veramente (se” sto interpretando correttamente) è eseguire doStuff con il valore di $i come argomento, assegnando loutput alla variabile stuff. Il modo per farlo è racchiudere il comando in $(). Ad esempio:

stuff="$(doStuff "$i")" 

Nota come ho anche messo virgolette intorno a tutto. Questo serve per evitare che la shell divida in parole cose che non vuoi che divida in parole (trasformerà un singolo argomento di /foo/bar baz in /foo/bar e baz).

Anche loutput della tua funzione è ciò che viene utilizzato come valore di ritorno, non return.

Dato che dovresti usare più virgolette, dovresti anche aggiungerle a tutto il resto. Ecco una versione completa del tuo script:

doStuff() { echo "${1}" >&2 printf "%s/hello" "$1"; } IFS=$"\n" for i in $(find "${directory}" -mindepth 1 -type d -name "${wildcard}"); do stuff="$(doStuff "${i}")" done 

Devi inserire la definizione della funzione prima di provare ad usarla. La shell non viene analizzata come i programmi compilati, dove passa attraverso il file più volte. È top-down.
Ho anche modificato doStuff per inviare il echo a STDERR dove verrà mostrato sul terminale, quindi printf invia a STDOUT dove verrà catturato nella variabile stuff.

Nota che questo avrà ancora un problema se una qualsiasi delle tue directory contiene una nuova riga. Tuttavia questa è una limitazione della shell. Lunico carattere che un percorso di file non può contenere è un carattere NULL (\0). Tuttavia bash e altre shell non possono memorizzare un carattere NULL in una stringa (non tutti, ma molti. So che zsh può), quindi puoi ” t usarlo come delimitatore.

Commenti

  • Volevo solo aggiungerlo se hai spazio prima / dopo =, si incasina. per esempio. MY_VAR = ' / some / path ' è valido ma MY_VAR = ' / some / path ' o MY_VAR = ' / some / path ' non è

Risposta

È un buon lavoro ma mostra che stai cercando di scrivere bash come se fosse un linguaggio di programmazione, quando in realtà è un semplice linguaggio di scripting. Il problema con la tua costruzione stuff=doStuff arg è che bash non significa ciò che pensi significhi. Per bash, stuff=doStuff è unassegnazione di variabile e arg è un comando. Ti suggerisco di leggere i seguenti due link:

Una versione funzionante di qualcosa di simile a quello che hai tu sarebbe

doStuff () { echo "$1/hello" } stuff=$(doStuff "$i") 

Risposta

La riga che dà lerrore non fa quello che pensi:

Per prima cosa imposta la variabile dambiente roba sulla stringa “doStuff”, quindi cerca di eseguire $ {i} come comando. E poiché $ {i} è una directory, fallisce con il messaggio di errore fornito.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *