Nyligen använde jag echo-kommandot med prefixet $. Till min förvåning var det ett fel. Mitt kommando var ungefär så här.
# !/bin/bash $(echo "a")
Felet var ..
./test1.sh: line 3: a: command not found
Kan någon förklara vad som händer här. Tack på förhand.
Svar
$(echo a)
är ett ”kommandosubstitution”. $(...)
kommer att ersättas med utdata från kommandot inom . Utgången i detta fall är a
, som skalet sedan försöker utföra. Skalet kan inte hitta kommandot a
och du får felmeddelandet.
Det är oklart vad din avsikt med detta var eller vad du förväntade dig att hända . Det är mycket ovanligt att vilja utföra resultatet av en kommandosubstitution.
Vissa program matar ut strängar som ska utvärderas av skalet. Det är därför möjligt att se kod som
eval "$(ssh-agent)"
som utvärderar (kör) utdata för det givna kommandot. Dessa kommandon har en strikt specificerad utgång och anses i allmänhet vara säkra att köra i I exemplet ovan startar ssh-agent
SSH-agentprocessen och matar ut några kommandon som ställer in lämpliga miljövariabler som ssh
klienten kommer senare att behöva använda agenten, till exempel
SSH_AUTH_SOCK=/tmp/ssh-Ppg1EO5eRIZp/agent.6017; export SSH_AUTH_SOCK; SSH_AGENT_PID=6018; export SSH_AGENT_PID; echo Agent pid 6018;
Detta utvärderas sedan av eval
.
eval
används här snarare än bara helt enkelt att använda $(ssh-agent)
eftersom utdata från ssh-agent
-kommandot är mer ett sammansatt kommando. Utan eval
skulle kommandoterminatorerna ;
vara speciella.
Exempel:
$ s="echo hello; echo world" $ $s hello; echo world $ eval "$s" hello world
Kommentarer
Svar
Du kan använda set -x
för att se vad skalet gör:
set -x $(echo "a") ++ echo a + a
Skalet kör echo a
och lägger utdata på kommandoraden. Detta är samma som om du hade försökt att utföra den här kommandoraden:
a
Skalet letar efter ett kommando a
i sökvägen (och till och med tidigare i funktionen, alias och hashlistor), hittar den inte och kastar därmed ett fel.
Det fungerar om utgången är ett giltigt kommando:
$(echo "ls")
Kommentarer
- kan du berätta för mig, vad för egentligen använder vi $ andra än att anropa en variabel.
- @Ashu Det används uppenbarligen också för kommandosubstitution – ditt fall. Förutom det visas i beräkning (
echo $((1+2+3))
), strängskapande ($'foo\nbar'
/$"foo"
) och (mindre skalrelaterat) i regexerna sombash
förstår ([[ foo =~ ^f..$ ]]
). Den används också för att ändra variabler på flera sätt:${foo#bar}
eval "$(dircolors)"
är en rimlig sak att göra. Samma som med flera andra kommandon som följer det mönstret, som gpg-agent.$(ssh-agent)
. Bra poäng.