Bagaimana saya bisa menjalankan skrip lokal pada mesin jarak jauh dan memasukkan argumen?

116

Saya telah menulis skrip yang berjalan dengan baik ketika dijalankan secara lokal:

./sysMole -time Aug 18 18

Argumen "-waktu" , "Agustus" , "18" , dan "18" berhasil diteruskan ke skrip.

Sekarang, skrip ini dirancang untuk dijalankan pada mesin jarak jauh tetapi, dari direktori lokal di mesin lokal. Contoh:

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

Itu juga berfungsi dengan baik. Tetapi masalah muncul ketika saya mencoba memasukkan argumen-argumen yang disebutkan di atas (-taman 18 Agustus 18) , misalnya:

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

Setelah menjalankan skrip itu, saya mendapatkan kesalahan berikut:

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

Tolong beritahu saya apa yang saya lakukan salah, ini sangat membuat frustrasi.

AllenD
sumber
1
"Bash -s" adalah salah satu cara Anda dapat menjalankan skrip dari input standar (mis. File).
AllenD

Jawaban:

160

Anda cukup dekat dengan contoh Anda. Ini berfungsi dengan baik ketika Anda menggunakannya dengan argumen seperti ini.

Contoh skrip:

$ more ex.bash 
#!/bin/bash

echo $1 $2

Contoh yang berfungsi:

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

Tetapi gagal untuk jenis argumen ini:

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

Apa yang sedang terjadi?

Masalah yang Anda temui adalah bahwa argumen -time,, atau --timedalam contoh saya, ditafsirkan sebagai beralih ke bash -s. Anda dapat menenangkan bashdengan menghentikannya dari mengambil argumen baris perintah yang tersisa untuk dirinya sendiri menggunakan --argumen.

Seperti ini:

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

Contohnya

# 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

CATATAN: Hanya untuk memperjelas bahwa di mana pun pengalihan muncul pada baris perintah tidak ada bedanya, karena sshmemanggil shell jarak jauh dengan gabungan argumennya, mengutip tidak membuat banyak perbedaan, kecuali ketika Anda perlu mengutip pada shell jauh seperti pada contoh # 4:

$ ssh  < ./ex.bash serverA "bash -s -- '<--time bye>' '<end>'"
<--time bye> <end>
slm
sumber
4
kamu seorang Genius! Apa yang harus saya lakukan untuk mencapai level Anda? Saya memiliki banyak pekerjaan yang dipotong. Terima kasih banyak.
AllenD
14
@ AllenD - teruslah bertanya, dan coba dan berpartisipasi di situs sebanyak yang Anda bisa. Saya selalu mencoba dan mempelajari sesuatu yang baru setiap hari. Sebelum pertanyaan Anda, saya juga tidak tahu bagaimana melakukan ini. 8-). Terima kasih atas pertanyaan anda!
slm
5
perhatikan bahwa pengalihan dapat muncul di setiap titik dalam perintah: misalnya bash -s -- --time bye < ./ex.bashatau bahkan < ./ex.bash bash -s -- --time bye. ini karena shell pertama-tama mengeluarkan instruksi pengalihan (terlepas dari di mana perintah itu berada), kemudian mengatur pengalihan, kemudian mengeksekusi sisa baris perintah dengan pengalihan di tempat.
lesmana
@sim Saya mencoba melakukan hal yang persis sama, tetapi dari dalam skrip, bukan dari baris perintah. Adakah yang tahu bagaimana melakukan ini? Untuk beberapa alasan, melampirkan jawaban tepat Anda di backticks tidak berfungsi sama sekali. Alih-alih menjalankan script yang ditentukan secara lokal, dan output dikirim sebagai perintah ke bash over ssh
krb686
@ krb686 - Saya akan menanyakannya sebagai Q. baru
slm
5

Tentang Menangani Argumen Sewenang-wenang

Jika Anda benar-benar hanya menggunakan string tunggal, yaitu. -time Aug 18 18, maka Anda dapat dengan mudah meng-hardcode-nya, dan jawaban yang ada memberi tahu Anda bagaimana melakukannya secara memadai. Di sisi lain, jika Anda harus melewati argumen yang tidak diketahui (seperti pesan yang akan ditampilkan di sistem lain, atau nama file yang dibuat di mana pengguna akhir dapat mengontrol namanya), maka diperlukan lebih banyak kehati-hatian.


Dengan bashatau kshsebagai/bin/sh

Jika kendali jarak jauh Anda /bin/shdisediakan oleh bash atau ksh, Anda dapat dengan aman melakukan yang berikut dengan daftar argumen yang tidak dipercaya, sehingga bahkan nama jahat (seperti $(rm -rf $HOME).txt) dapat disampaikan sebagai argumen dengan aman:

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"
}

Dengan Setiap POSIX-Compliant /bin/sh

Agar aman terhadap data argumen yang cukup berbahaya (berusaha mengambil keuntungan dari kutipan yang tidak sesuai dengan POSIX yang digunakan oleh printf %qdalam bash ketika karakter yang tidak dapat dicetak hadir dalam string yang diloloskan) bahkan dengan /bin/shyang merupakan baseline-POSIX (seperti dashatau ash), itu jadi sedikit lebih menarik:

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
}

Penggunaan (untuk salah satu di atas)

Fungsi-fungsi yang diberikan di atas kemudian dapat dipanggil sebagai:

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

...atau...

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

katakanlah aa adalah file lokal yang berisi ls

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

ubah 127.0.0.1 menjadi apa pun ip jarak jauh Anda

keduanya memberikan pesan tentang alokasi pseudo tty tetapi mereka bekerja.

$ cat a.a | ssh 127.0.0.1

$ ssh 127.0.0.1 <a.a

Atau

$ cat a.a | ssh 127.0.0.1 bash or

$ ssh 127.0.0.1 bash < a.a

barlop
sumber
2
Saya berjuang untuk melihat seberapa jauh ini menjawab pertanyaan.
ChrisWue
Kualitas dan formatnya diragukan. Saya juga tidak melihat informasi bermanfaat baru yang tidak ada dalam jawaban yang diterima.
Julie Pelletier
@JuliePelletier Saya memberikan beberapa contoh 'kucing' tidak dalam jawaban yang diterima. Adalah baik untuk mengetahui cara-cara alternatif dalam melakukan sesuatu.
barlop
Itu bukan hal yang baik; kucingmu tidak berguna.
Scott
2
Ya Tuhan. Saya meninggalkan tautan ke penggunaan kucing yang tidak berguna karena saya berasumsi bahwa setidaknya setiap orang sudah mendengar ungkapan itu sekarang; rupanya itu anggapan buruk di pihak saya.
Scott