Bash-komentosarjassa käytän hakua hakemaan kansionimet jokerimerkillä:
for i in $(find ${directory} -mindepth 1 -type d -name ${wildcard}); do stuff=doStuff ${i} done doStuff() { echo ${1} return ${1}"/hello"; }
Ongelmana on, että kun teen tämän, saan seuraava virhe (sanotaan, että $ {i} vastaa ”home / me / my_directory”):
line 111: "/home/me/my_directory": is a directory.
(rivi 111 on ”doStuff” -rivi ”)
Olen yrittänyt tehdä tämän, turhaan:
for i in $(find ${directory} -mindepth 1 -type d -name ${wildcard}); do stuff=doStuff "${i}" done
Ilmeisesti se johtuu siitä, että ohjelma yrittää suorittaa hakemistoa, mutta haluan sen vain merkkijonona, jota voin muokata.
Kommentit
vastaus
Lainausmerkit ja komentojen korvaaminen ovat kysymyksesi tässä.
Erityinen ongelma, johon törmäät, johtuu siitä, että kuori yrittää suorittaa komentoa nimeltä /home/me/my_directory
ympäristömuuttujan stuff=doStuff
kanssa.
Mitä todella haluat (jos tulkitsen oikein) on ajaa doStuff
, jonka arvo on $i
argumenttina, määrittäen lähdön muuttujalle stuff
. Tapa tehdä tämä on kietoa komento $()
. Esimerkiksi:
stuff="$(doStuff "$i")"
Huomaa, kuinka laittoin myös lainauksia kaiken ympärille. Tämän tarkoituksena on estää kuorta jakamasta asioita, joita et halua sen jakavan (se ”muuttaa yhden argumentin /foo/bar baz
osaksi /foo/bar
ja baz
).
Myös funktion lähdössä käytetään paluuarvoa, ei return
.
Koska sinun pitäisi käyttää enemmän lainausmerkkejä, sinun on lisättävä ne myös kaikkeen muuhun. Tässä on komentosarjosi täydellinen versio:
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
Funktion määritelmä on laitettava ennen kuin yrität käyttää sitä. Shelliä ei jäsennellä kuten käännettyjä ohjelmia, missä se käy tiedoston läpi useita kertoja. Se on ylhäältä alas.
Olen myös muokannut doStuff
-kuvaketta lähettämään echo
STDERR: lle, missä se näytetään päätelaitteessa, ja sitten printf
lähettää STDOUT: lle, missä se kaapataan muuttujaan stuff
.
Huomaa, että tässä on edelleen ongelma, jos jokin hakemistoistasi sisältää uuden rivin. Tämä on kuitenkin kuoren rajoitus. Ainoa merkki, jota tiedostopolku ei voi include on NULL-merkki (\0
). Bash ja muut kuoret eivät kuitenkaan voi tallentaa NULL-merkkiä merkkijonoon (eivät kaikki, mutta monet. Tiedän, että zsh voi), joten voit ” t käytä sitä erottimena.
Kommentit
- Halusin vain lisätä, että jos sinulla on tilaa ennen / jälkeen
=
, se sekoittaa. esimerkiksi. MY_VAR = ' / some / path ' on kelvollinen, mutta MY_VAR = ' / some / polku ' tai MY_VAR = ' / some / path ' ei ole
Vastaus
Se on hyvä ponnistus, mutta se osoittaa, että yrität kirjoittaa bash
ikään kuin se olisi ohjelmointikieli, kun se on itse asiassa yksinkertainen komentosarjakieli. stuff=doStuff arg
-rakenteen ongelmana on, että bash
se ei tarkoita sitä, mitä luulet sen tarkoittavan. Kohteeseen bash
stuff=doStuff
on muuttujan määritys ja arg
on komento. Ehdotan, että luet seuraavat kaksi linkkiä:
- Kuinka voin tallentaa komennon palautusarvon ja / tai tuotoksen muuttujaan?
- Kuinka palautan merkkijonon (tai suuren tai negatiivisen luvun) funktiosta? ”return” antaa minun antaa vain numeron 0-255.
Toimiva versio jotain samanlaista kuin sinulla olisi
doStuff () { echo "$1/hello" } stuff=$(doStuff "$i")
Vastaa
Virheen antava rivi ei tee sitä mitä luulet tekevänsä:
Se asettaa ensin ympäristömuuttujatiedot merkkijonoksi ”doStuff” ja yrittää sitten suorittaa $ {i} -komennon. Ja koska $ {i} on hakemisto, se epäonnistuu annetulla virheilmoituksella.
find "${directory}" -mindepth 1 -type d -name "${wildcard}" -print0 | xargs -0 doStuff
//a wrong bash line comment
#a correct bash line comment