Başına zanco cevabı , size uzak bir komut veren değil ssh
kabuk komut satırını ayrıştırır nasıl verilir. Bu sorunu çözmek için, ssh
komut çağrınızın sözdizimini , uzak komut sözdizimsel olarak doğru, çok satırlı bir dizeden oluşacak şekilde değiştirin.
Kullanılabilecek çeşitli sözdizimleri vardır. Örneğin, komutlar bash
ve sh
ve muhtemelen diğer kabuklara da dahil edilebildiğinden, en basit çözüm ssh
kabuk kabartmasını yorumlu metinlerle birleştirmektir :
ssh user@server /bin/bash <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
Yukarıdakilerin olmadan çalıştırmanın /bin/bash
uyarıya neden olacağını unutmayın Pseudo-terminal will not be allocated because stdin is not a terminal
. Ayrıca not o EOT
ki, tek tırnak ile çevrilidir bash
bir şekilde yorumlu metin tanır Yorumlu metin komut metin için olduğu gibi geçilecek ve böylece yerel değişken interpolasyon kapatarak, ssh
.
Bir boru hayranı iseniz, yukarıdakileri aşağıdaki gibi yeniden yazabilirsiniz:
cat <<'EOT' | ssh user@server /bin/bash
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
Aynı uyarı /bin/bash
yukarıdaki hususlar için de geçerlidir.
Bir başka geçerli yaklaşım, çok satırlı uzaktan komutun, bash
değişken enterpolasyonun çoklu katmanlarını aşağıdaki gibi kullanarak tek bir dize olarak geçirmektir :
ssh user@server "$( cat <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
)"
Yukarıdaki çözüm bu sorunu aşağıdaki şekilde giderir:
ssh user@server
Bash tarafından ayrıştırılır ve olduğu yorumlanır ssh
komutu, ardından bir bağımsız değişken user@server
geçirilecek ssh
komutu
"
tamamlandığında ssh
komuta iletilecek bir argüman içerecek enterpolasyonlu bir dize başlatır ; bu durumda, ssh
yürütmek için uzaktan komut olarak yorumlanır.user@server
$(
çıktı, çevreleyen enterpolasyonlu dize tarafından yakalanacak şekilde yürütülecek bir komutu başlatır
cat
takip eden dosyanın içeriğini çıktılamak için kullanılan bir komuttur. Çıkışı cat
yakalanan enterpolasyonlu dizeye geri aktarılacaktır
<<
bash heredoc başlar
'EOT'
yorumlu metin adının EOT olduğunu belirtir. '
EOT'yi çevreleyen tek alıntılar , yorumlu yazının, içeriğin bash tarafından enterpole edilmediği, daha ziyade değişmez biçimde aktarıldığı özel bir yorumlu metin olan nowdoc olarak ayrıştırılması gerektiğini belirtir.
Karşılaşılan <<'EOT'
ve <newline>EOT<newline>
nowdoc çıktısına eklenecek herhangi bir içerik
EOT
nowdoc öğesini sonlandırır, bu nedenle nowdoc geçici dosyası oluşturulur ve çağrı cat
komutuna iletilir . cat
nowdoc çıktısını alır ve çıktıyı yakalanan enterpolasyonlu dizeye geri aktarır
)
yürütülecek komutu sonlandırır
"
yakalanan enterpolasyonlu dizgiyi sonlandırır. Enterpolasyonlu dizenin içeriği, ssh
tek bir komut satırı bağımsız değişkeni olarak iletilir ssh
ve bu komut, yürütmek için uzaktan komut olarak yorumlanıruser@server
Gibi harici araçlar kullanmaktan kaçınmanız gerekiyorsa cat
ve bir yerine iki ifade read
almayı düşünmüyorsanız, SSH komutunu oluşturmak için yerleşik bir yorumlu metinle kullanın:
IFS='' read -r -d '' SSH_COMMAND <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
ssh user@server "${SSH_COMMAND}"
ssh user@server /bin/bash <<EOT…