A bash szkriptemben a find-ot használom a mappanevek helyettesítő karakterekkel történő megszerzéséhez:
for i in $(find ${directory} -mindepth 1 -type d -name ${wildcard}); do stuff=doStuff ${i} done doStuff() { echo ${1} return ${1}"/hello"; }
A probléma az, hogy amikor ezt csinálom, akkor kapok a következő hiba (tegyük fel, hogy $ {i} megfelel a “home / me / my_directory” -nak):
line 111: "/home/me/my_directory": is a directory.
(a 111. sor a “doStuff” sor “)
Megpróbáltam ezt csinálni, eredménytelenül:
for i in $(find ${directory} -mindepth 1 -type d -name ${wildcard}); do stuff=doStuff "${i}" done
Nyilván azért van ez, mert a program megpróbálja végrehajtani a könyvtárat, de csak egy karaktersorozatként szeretném, amelyet kezelni tudnék.
Megjegyzések
Válasz
Idézetek és a parancsok cseréje a kérdésed.
Az a konkrét probléma, amibe belefut, az az, hogy a shell megpróbálja futtatni a a (z) stuff=doStuff
környezeti változóval.
Amit igazán szeretnél (ha jól értelmezem), az a doStuff
argumentumként a $i
értékkel, a kimenetet a stuff
változóhoz rendelve. Ennek módja az, hogy a parancsot be kell csomagolni a $()
fájlba. Például:
stuff="$(doStuff "$i")"
Figyelem, hogy én is teszek idézőjeleket minden köré. Ez megakadályozza, hogy a héj szétválassza azokat a dolgokat, amelyeket nem akarsz szó szerint megosztani (ez a /foo/bar baz
egyetlen argumentumát /foo/bar
és baz
).
A függvény kimenete is az, amit visszatérési értékként használunk, nem pedig return
.
Mivel több idézetet kellene használnia, ezeket hozzá kell adnia minden máshoz is. Itt van a szkript teljes verziója:
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
Mielőtt megpróbálná használni, be kell adnia a függvénydefiníciót. A Shell nem értelmezhető úgy, mint a lefordított programok, ahol többször is átmegy a fájlon. Felülről lefelé.
A doStuff
fájlt is módosítottam a echo
az STDERR-hez, ahol ez megjelenik a terminálon, majd az printf
elküldi az STDOUT-nak, ahol a stuff
.
Ne feledje, hogy ennek továbbra is problémája lesz, ha valamelyik címtár új sort tartalmaz. Ez azonban a héj korlátozása. A fájl elérési útjának egyetlen karaktere a include egy NULL karakter (\0
). Azonban a bash és más héjak nem tárolhatnak NULL karaktert egy karakterláncban (nem mindegyik, de sok. Tudom, hogy a zsh képes), így megteheti ” ne használd elválasztóként.
Megjegyzések
- Csak annyit akartam hozzáfűzni, hogy ha van helyed
=
, elrontja. például. MY_VAR = ' / some / path ' érvényes, de MY_VAR = ' / some / ' vagy MY_VAR = ' / path ' elérési út nem
Válasz
Ez jó erőfeszítés, de azt mutatja, hogy bash
mintha programozási nyelv lenne, amikor valójában egyszerű szkriptnyelv. A stuff=doStuff arg
konstrukcióval az a probléma, hogy bash
az nem azt jelenti, amit ön szerint jelent. A bash
címre a stuff=doStuff
változó hozzárendelés, az arg
pedig parancs. Azt javaslom, olvassa el a következő két linket:
- Hogyan tárolhatom a parancs visszatérési értékét és / vagy kimenetét egy változóban?
- Hogyan adhatok vissza egy karakterláncot (vagy nagy számot, vagy negatív számot) egy függvényből? A “return” segítségével csak 0 és 255 közötti számot adhatok meg.
Valaminek a működőképes változata, mint ami lenne
doStuff () { echo "$1/hello" } stuff=$(doStuff "$i")
Válasz
A hibát adó sor nem azt csinálja, amit Ön gondol:
Először a környezeti változó cuccait állítja a “doStuff” karakterláncra, majd megpróbálja végrehajtani a $ {i} parancsot. És mivel a $ {i} könyvtár, ezért a megadott hibaüzenettel nem sikerül.
find "${directory}" -mindepth 1 -type d -name "${wildcard}" -print0 | xargs -0 doStuff
//a wrong bash line comment
a#a correct bash line comment