' er en mappe ' fejl, når du prøver at videregive biblioteksnavn til funktion

I mit bash-script bruger jeg find til at hente mappenavnene med jokertegn:

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

Problemet er, at når jeg gør dette, får jeg følgende fejl (lad os sige, at $ {i} svarer til “hjem / mig / min_katalog”):

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

(linje 111 er linjen med “doStuff “)

Jeg har forsøgt at gøre dette, til ingen nytte:

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

Det er tilsyneladende fordi programmet forsøger at udføre katalog, men jeg vil bare have det som en streng, som jeg kan manipulere.

Kommentarer

  • Hmmm …. Ifølge bash man-siden. … Den indbyggede returkommando i bash bruges til at vende tilbage til en EXIT-kode (heltal), ikke nogen type strengparameter.
  • Du kan også prøve find "${directory}" -mindepth 1 -type d -name "${wildcard}" -print0 | xargs -0 doStuff
  • googlere : en anden god kilde til at få denne fejlmeddelelse ge er //a wrong bash line comment i stedet for #a correct bash line comment

Svar

Citater og udskiftning af kommandoer er dine problemer her.

Det specifikke emne, du løber ind i, er fordi skallen prøver at køre en kommando kaldet /home/me/my_directory med miljøvariablen stuff=doStuff.
Det du virkelig ønsker (hvis jeg fortolker korrekt) er at køre doStuff med værdien $i som et argument, der tildeler output til variablen stuff. Måden at gøre dette på er at indpakke din kommando i $(). For eksempel:

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

Bemærk hvordan jeg også sætter tilbud omkring alt. Dette er for at forhindre, at skallen orddeler ting, du ikke vil have, at den opdeles i ord (det vil vende et enkelt argument af /foo/bar baz til /foo/bar og baz).

Også output af din funktion er det, der bliver brugt som returværdi, ikke return.

Da du skulle bruge flere tilbud, skal du også føje dem til alt andet. Her er en komplet version af dit 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 

Du skal sætte funktionsdefinitionen, før du prøver at bruge den. Shell er ikke analyseret som kompilerede programmer, hvor den går gennem filen flere gange. Det er top-down.
Jeg har også ændret doStuff for at sende echo til STDERR hvor det vil blive vist på terminalen, og derefter sender printf til STDOUT, hvor det bliver fanget i variablen stuff.

Bemærk, at dette stadig vil have et problem, hvis nogen af dine mapper indeholder en ny linje. Dette er dog en begrænsning af skallen. Det eneste tegn, en filsti ikke kan contain er en NULL-char (\0). Bash og andre skaller kan dog ikke gemme en NULL-char i en streng (ikke alle, men mange. Jeg ved, at zsh kan), så du kan ” Brug det ikke som en afgrænser.

Kommentarer

  • Vil bare tilføje, at hvis du har plads før / efter =, det ødelægger. for eksempel. MY_VAR = ' / some / path ' er gyldig, men MY_VAR = ' / some / sti ' eller MY_VAR = ' / some / sti ' er ikke

Svar

Det er en god indsats, men det viser, at du prøver at skrive bash som om det var et programmeringssprog, når det faktisk er et simpelt script-sprog. Problemet med din stuff=doStuff arg konstruktion er, at for bash betyder det ikke, hvad du mener, det betyder. Til bash er stuff=doStuff en variabel tildeling, og arg er en kommando. Jeg foreslår, at du læser følgende to links:

En fungerende version af noget, der ligner det, du har, ville være

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

Svar

Linjen, der giver fejlen, gør ikke, hvad du tror, den gør:

Det indstiller først miljøvariabelforretningen til strengen “doStuff” og forsøger derefter at udføre $ {i} som en kommando. Og da $ {i} er et bibliotek, fejler det med den givne fejlmeddelelse.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *