' is een directory ' fout bij het doorgeven van directorynaam aan functie

In mijn bash-script gebruik ik find om de mapnamen met jokertekens te krijgen:

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

Het probleem is dat wanneer ik dit doe, ik de volgende foutmelding (laten we zeggen dat $ {i} overeenkomt met “home / me / mijn_directory”):

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

(regel 111 is de regel met “doStuff “)

Ik heb dit geprobeerd, maar het mocht niet baten:

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

Blijkbaar is het omdat het programma probeert de directory, maar ik wil het gewoon als een string die ik kan manipuleren.

Reacties

  • Hmmm …. Volgens de bash man-pagina. … Het ingebouwde return-commando in bash wordt gebruikt om een EXIT-code (geheel getal) te retourneren, geen tekenreeksparameter.
  • Je kunt ook find "${directory}" -mindepth 1 -type d -name "${wildcard}" -print0 | xargs -0 doStuff
  • googlers : nog een geweldige bron om deze foutmelding te krijgen ge is //a wrong bash line comment in plaats van #a correct bash line comment

Antwoord

Aanhalingstekens en vervanging van commandos zijn hier uw problemen.

Het specifieke probleem dat u “tegenkomt, is omdat de shell een commando probeert uit te voeren met de naam /home/me/my_directory met de omgevingsvariabele stuff=doStuff.
Wat je echt wilt (als ik” m correct interpreteer) is om doStuff met de waarde $i als argument, waarbij de uitvoer wordt toegewezen aan de variabele stuff. De manier om dit te doen is door uw commando in $() te plaatsen. Bijvoorbeeld:

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

Let op hoe ik ook overal aanhalingstekens plaats. Dit is om te voorkomen dat de shell dingen opsplitst die je niet wilt dat het woord splitst (het “zal een enkel argument van /foo/bar baz veranderen in /foo/bar en baz).

Ook de output van je functie is wat wordt gebruikt als de retourwaarde, niet return.

Omdat je meer aanhalingstekens zou moeten gebruiken, zou je ze ook aan al het andere moeten toevoegen. Hier is een volledige versie van uw 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 

U moet de functiedefinitie plaatsen voordat u deze probeert te gebruiken. Shell wordt niet geparseerd zoals gecompileerde programmas, waar het meerdere keren door het bestand gaat. Het is van boven naar beneden.
Ik heb ook doStuff gewijzigd om de echo naar STDERR waar het op de terminal getoond zal worden, en vervolgens stuurt de printf naar STDOUT waar het wordt vastgelegd in de variabele stuff.

Merk op dat dit nog steeds een probleem zal hebben als een van uw mappen een nieuwe regel bevat. Dit is echter een beperking van de shell. Het enige teken dat een bestandspad niet kan contain is een NULL-teken (\0). Bash en andere shells kunnen echter geen NULL-teken in een string opslaan (niet alle, maar veel. Ik weet dat zsh kan), dus je kunt ” gebruik het niet als scheidingsteken.

Opmerkingen

  • Ik wilde dat alleen toevoegen als je ruimte voor / na =, het maakt een fout. bijv. MY_VAR = ' / some / path ' is geldig maar MY_VAR = ' / some / pad ' of MY_VAR = ' / sommige / pad ' is niet

Antwoord

Dat is een goede poging, maar het laat zien dat je probeert bash alsof het een programmeertaal is, terwijl het eigenlijk een eenvoudige scripttaal is. Het probleem met je stuff=doStuff arg constructie is dat bash het niet betekent wat je denkt dat het betekent. Aan bash, stuff=doStuff is een variabeletoewijzing en arg is een commando. Ik stel voor dat je de volgende twee links leest:

Een werkende versie van iets dat lijkt op wat je hebt, zou zijn

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

Answer

De regel met de fout doet niet wat je denkt dat hij doet:

Het stelt eerst de omgevingsvariabele stuff in op de string “doStuff”, en probeert vervolgens $ {i} uit te voeren als een commando. En aangezien $ {i} een directory is, mislukt dat met de gegeven foutmelding.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *