Yerel komut dosyasını uzaktaki makinede nasıl çalıştırabilirim ve bağımsız değişkenleri nasıl ekleyebilirim?


116

Yerel olarak çalıştırıldığında iyi çalışan bir komut dosyası yazdım:

./sysMole -time Aug 18 18

"-Time" , "Aug" , "18" ve "18" argümanları başarıyla komut dosyasına iletilir.

Şimdi, bu komut dosyası uzak bir makinede ancak yerel makinedeki yerel bir dizinden yürütülecek şekilde tasarlandı. Örnek:

ssh root@remoteServer "bash -s" < /var/www/html/ops1/sysMole

Bu da iyi çalışıyor. Ancak, yukarıda bahsedilen argümanları eklemeye çalıştığımda sorun ortaya çıkıyor ( örneğin, 18 Ağustos 18) :

ssh root@remoteServer "bash -s" < /var/www/html/ops1/sysMole -time Aug 18 18

Bu betiği çalıştırdıktan sonra aşağıdaki hatayı alıyorum:

bash: cannot set terminal process group (-1): Invalid argument
bash: no job control in this shell

Lütfen yanlış yaptığımı söyle, bu çok sinir bozucu.


1
"Bash -s", bir komut dosyasını standart girişten (yani bir dosyadan) yürütmenin yollarından biridir.
AllenD

Yanıtlar:


160

Örneğine oldukça yakındın. Bu gibi argümanlarla kullandığınızda gayet iyi çalışıyor.

Örnek komut dosyası:

$ more ex.bash 
#!/bin/bash

echo $1 $2

İşe yarayan örnek:

$ ssh serverA "bash -s" < ./ex.bash "hi" "bye"
hi bye

Ancak bu tür argümanlar için başarısız olur:

$ ssh serverA "bash -s" < ./ex.bash "--time" "bye"
bash: --: invalid option
...

Neler oluyor?

Karşılaştığınız sorun, tartışmanın -timeveya --timebenim örneğimde bir geçiş olarak yorumlanmasıdır bash -s. bashArgümanı kullanarak, kalan komut satırı argümanlarından herhangi birini kendisinin almasını sonlandırarak pasifleştirebilirsiniz --.

Bunun gibi, böyle:

$ ssh root@remoteServer "bash -s" -- < /var/www/html/ops1/sysMole -time Aug 18 18

Örnekler

# 1:

$ ssh serverA "bash -s" -- < ./ex.bash "-time" "bye"
-time bye

# 2:

$ ssh serverA "bash -s" -- < ./ex.bash "--time" "bye"
--time bye

# 3:

$ ssh serverA "bash -s" -- < ./ex.bash --time "bye"
--time bye

# 4:

$ ssh  < ./ex.bash serverA "bash -s -- --time bye"
--time bye

NOT: Yeniden yönlendirmenin komut satırında göründüğü her yerde fark sshyaratmaz , çünkü yine de bağımsız değişkenlerini bir araya getirerek uzaktaki bir kabuğu çağırır, alıntı yapmak, uzaktaki kabuktan alıntı yapmanız gerektiğinden başka bir fark yaratmaz. örnek # 4'teki gibi:

$ ssh  < ./ex.bash serverA "bash -s -- '<--time bye>' '<end>'"
<--time bye> <end>

4
sen bir dehasın! Seviyene ulaşmak için ne yapmam gerekiyor? Çok işim kesildi. Çok teşekkürler.
AllenD

14
@AllenD - Sadece soru sormaya devam edin ve mümkün olduğunca siteye katılmaya çalışın. Her zaman yeni bir şeyler öğrenmeye çalışırım. Sorunuzdan önce, bunu nasıl yapacağımı da bilmiyordum. 8-). Sorunuz için teşekkürler!
slm

5
yönlendirme komutunun herhangi bir noktasında görünebilir: örneğin bash -s -- --time bye < ./ex.bashveya hatta < ./ex.bash bash -s -- --time bye. Bunun nedeni, kabuğun önce yönlendirme talimatını (komutun neresinde olduğuna bakılmaksızın) alıp yeniden yönlendirmeyi kurması, sonra komut satırının geri kalanını yeniden yönlendirme ile birlikte yürütmesidir.
lesmana

@sim Aynı şeyi yapmaya çalışıyorum ama bir komut dosyasından komut satırından değil. Bunun nasıl yapılacağı hakkında bir fikrin var mı? Bazı nedenlerden dolayı, tam cevabınızı backticks'e dahil etmek hiç işe yaramaz. Bunun yerine yerel olarak belirtilen betiği çalıştırır ve çıktı ssh üzerinden
bash'a

@ krb686 - Yeni bir soru sormak isterim
slm

5

Keyfi Argümanların Ele Alınması Üzerine

Gerçekten sadece tek bir dize kullanıyorsanız, yani. -time Aug 18 18, o zaman sadece basit bir şekilde kod yazabilirsiniz ve mevcut cevaplar size bunu nasıl uygun şekilde yapacağınızı söyler. Öte yandan, bilinmeyen argümanları iletmeniz gerekiyorsa (diğer sistemde görüntülenecek bir mesaj veya son kullanıcıların adını kontrol edebileceği bir dosyanın adı gibi), o zaman daha fazla özen gösterilmesi gerekir.


İle bashveya ksholarak/bin/sh

Eğer uzaktan kumandanız /bin/shbash veya ksh tarafından sağlanmışsa, aşağıdakileri güvenli olmayan bir argüman listesiyle güvenle yapabilirsiniz, böylece kötü niyetli isimler bile (örneğin $(rm -rf $HOME).txt) güvenli bir şekilde argüman olarak iletilebilir:

runRemote() {
  local args script

  script=$1; shift

  # generate eval-safe quoted version of current argument list
  printf -v args '%q ' "$@"

  # pass that through on the command line to bash -s
  # note that $args is parsed remotely by /bin/sh, not by bash!
  ssh user@remote-addr "bash -s -- $args" < "$script"
}

Herhangi bir POSIX Uyumlu ile /bin/sh

Yeterince kötü niyetli argüman veri karşı güvenli olması için (kullandığı tırnaklama POSIX olmayan şikayette yararlanmak teşebbüs printf %qbile Yazdırılamayan karakterlerin çıkış dize da mevcut olduğunda bash) bir /bin/shbazal-POSIX (gibi olduğunu dashya ash), o biraz daha ilginçleşiyor:

runRemote() {
  local script=$1; shift
  local args
  printf -v args '%q ' "$@"
  ssh user@remote-addr "bash -s" <<EOF

  # pass quoted arguments through for parsing by remote bash
  set -- $args

  # substitute literal script text into heredoc
  $(< "$script")

EOF
}

Kullanım (yukarıdakilerden herhangi biri için)

Yukarıda verilen işlevler şu şekilde çağrılabilir:

# if your time should be three arguments
runRemote /var/www/html/ops1/sysMole -time Aug 18 18

...veya...

# if your time should be one string
runRemote /var/www/html/ops1/sysMole -time "Aug 18 18"

-3

aa, ls içeren yerel bir dosyadır.

$ssh servername "cat | bash" < a.a

127.0.0.1’i değiştirerek uzaktaki IP’niz ne olursa olsun

Bu ikisi sözde tty tahsisi hakkında bir mesaj veriyorlar ancak çalışıyorlar.

$ cat a.a | ssh 127.0.0.1

$ ssh 127.0.0.1 <a.a

Veya

$ cat a.a | ssh 127.0.0.1 bash or

$ ssh 127.0.0.1 bash < a.a


2
Bunun soruyu ne kadar cevapladığını görmek için mücadele ediyorum.
ChrisWue,

Kalite ve biçimlendirme şüphelidir. Kabul edilen cevapta bulunmayan yeni faydalı bilgiler göremiyorum.
Julie Pelletier

@JuliePelletier Kabul edilen cevapta olmayan bazı 'kedi' örnekleri verdim. Bir şeyler yapmanın alternatif yollarını bilmek iyidir.
barlop

Bu iyi bir şey değil; senin kedilerin işe yaramaz.
Scott

2
Aman tanrım. Yararsız kedi kullanımı bağlantısını bıraktım çünkü herkesin ifadeyi şimdiye kadar en azından duyduğunu varsaymıştım; görünüşe göre bu benim açımdan kötü bir varsayımdı.
Scott
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.