Jeg skrev et veldig grunnleggende skript for kommandosubstitusjon som er under:
#!/bin/bash files=$(ls *.fastq); echo $files
Katalogen inneholder en mengde .fastq-filer, og jeg vil bare bruke ekkokommandoen til å sende dem ut
Sriptet ovenfor sender ut fastq-filer med et mellomrom mellom hvert fastq-filnavn.
Når jeg bruker det på denne måten
#!/bin/bash files=$(ls *.fastq); echo "$files"
skriver det ut resultatene på nye linjer.
Hvorfor er det slik? Er det noe å gjøre med kommandosubstitusjon?
Takk
Svar
Når det refereres til en variabel, er det er generelt tilrådelig å legge navnet sitt i dobbelt anførselstegn. Dette forhindrer tolking av alle spesialtegn i den siterte strengen – unntatt $
, `
(backquote) og \
(flukt). Hvis du holder $
som et spesialtegn i doble anførselstegn, kan du referere til en sitert variabel («$ variabel»), det vil si å erstatte variabelen med verdien.
Bruk doble anførselstegn for å forhindre orddeling. Et argument innesluttet i dobbelt anførselstegn presenterer seg som et enkelt ord, selv om det inneholder mellomromsseparatorer.
f.eks.
variable1="a variable containing five words" COMMAND This is $variable1 # Executes COMMAND with 7 arguments: # "This" "is" "a" "variable" "containing" "five" "words" COMMAND "This is $variable1" # Executes COMMAND with 1 argument: # "This is a variable containing five words"
Å legge inn argumentene til et ekkouttrykk i doble anførselstegn er bare nødvendig når orddeling eller bevaring av mellomrom er et problem.
For mer info og eksempler gå her
Svar
Du har nye linjer fordi ls
setter dem på separate linjer. Nylinjene forsvinner uten anførselstegn, fordi skallet (bash) sender hver ikke sitert mellomromsskilt tekst til kommandoen som et eget argument.
Merk: Kommandosubstitusjonen gjøres av skallet, ikke av ls
, så du trenger ikke ls
.
Derfor kan du gjøre
#!/bin/bash echo *.fastq
eller
#!/bin/bash files="*.fastq" echo "$files"
Kommentarer
Svar
Når du refererer til en variabel uten anførselstegn rundt den (f.eks. echo $files
), deler skallet verdien fra hverandre på hvitt mellomrom og sender hvert ord som et eget kommandolinjealternativ. Newlines behandles på samme måte som alle andre mellomrom. echo
-programmet ser ikke de nye linjetegnene i det hele tatt; det får bare en rekke strenger, som hver er et enkelt filnavn.
Når du refererer til en variabel i anførselstegn (f.eks. echo "$files"
), gjør ikke skallet noe hvitt mellomrom; i stedet overfører den hele verdien, umodifisert, som et enkelt argument. echo
-programmet mottar en lang streng som inkluderer de nye linjetegnene.
Variabler til side, dette er den samme oppførselen du får med anførselstegn rundt bokstavelige verdier. Hvis du skriver echo foo bar
, blir mellomrommene fjernet av skallet og echo
får bare strengene foo
og bar
, og det vil skrive ut strengene med ett mellomrom mellom hverandre, siden det er slik det er kodet for å kombinere flere argumenter. Hvis du skriver echo "foo bar"
, echo
får enkeltstrengen foo bar
og vil skrive den ut som den er.
ls
vil sende ut samme somls -x
når til en tty, og somls -1
når ikke. Bruk derforls -x
for å få det du ønsker.