GNU/Linux >> Belajar Linux >  >> Linux

Oring Dengan Benar Dalam Perintah Atas Ssh?

Ketika saya mencoba menjalankan pkill -f dari jarak jauh melalui ssh, dan coba buang kemungkinan kode kesalahan (untuk melanjutkan skrip saya yang lain meskipun tidak ada proses yang ditemukan), || true tidak berperilaku seperti yang saya harapkan.

$ pkill asdf || true
$ echo $?
0
$ pkill -f asdf || true
$ echo $?
0
$ ssh [email protected] "pkill asdf || true"
$ echo $?
0
$ ssh [email protected] "pkill -f asdf || true"
255

Saya kira itu adalah ssh yang mengembalikan 255, bukan perintah di antara tanda kutip, tetapi mengapa?

Jawaban yang Diterima:

Anggapan Anda bahwa itu ssh sendiri yang mengembalikan status keluar 255 benar. ssh halaman manual menyatakan bahwa:

ssh keluar dengan status keluar dari perintah jarak jauh atau dengan 255 jika terjadi kesalahan.

Jika Anda hanya menjalankan ssh [email protected] "pkill -f asdf" , kemungkinan besar Anda akan mendapatkan status keluar 1 , sesuai dengan pkill status untuk “Tidak ada proses yang cocok ”.

Bagian yang menantang adalah memahami mengapa terjadi kesalahan dengan SSH saat Anda menjalankan

ssh [email protected] "pkill -f asdf || true"

Perintah jarak jauh SSH

Server SSH meluncurkan shell untuk menjalankan perintah jarak jauh. Berikut ini contoh tindakannya:

$ ssh server "ps -elf | tail -5"
4 S root     35323  1024 12  80   0 - 43170 poll_s 12:01 ?        00:00:00 sshd: anthony [priv]
5 S anthony  35329 35323  0  80   0 - 43170 poll_s 12:01 ?        00:00:00 sshd: [email protected]
0 S anthony  35330 35329  0  80   0 - 28283 do_wai 12:01 ?        00:00:00 bash -c ps -elf | tail -5
0 R anthony  35341 35330  0  80   0 - 40340 -      12:01 ?        00:00:00 ps -elf
0 S anthony  35342 35330  0  80   0 - 26985 pipe_w 12:01 ?        00:00:00 tail -5

Perhatikan bahwa shell default adalah bash dan bahwa perintah jarak jauh bukanlah perintah sederhana tetapi sebuah saluran, “urutan dari satu atau lebih perintah yang dipisahkan oleh operator kontrol | ”.

Shell Bash cukup pintar untuk menyadari bahwa jika perintah diteruskan oleh -c option adalah perintah sederhana, ia dapat mengoptimalkan dengan tidak benar-benar membuat proses baru, yaitu, secara langsung exec s perintah sederhana alih-alih melalui langkah ekstra fork ing sebelum exec s. Berikut adalah contoh yang terjadi saat Anda menjalankan perintah sederhana jarak jauh (ps -elf dalam hal ini):

$ ssh server "ps -elf" | tail -5
1 S root     34740     2  0  80   0 -     0 worker 11:49 ?        00:00:00 [kworker/0:1]
1 S root     34762     2  0  80   0 -     0 worker 11:50 ?        00:00:00 [kworker/0:3]
4 S root     34824  1024 31  80   0 - 43170 poll_s 11:51 ?        00:00:00 sshd: anthony [priv]
5 S anthony  34829 34824  0  80   0 - 43170 poll_s 11:51 ?        00:00:00 sshd: [email protected]
0 R anthony  34830 34829  0  80   0 - 40340 -      11:51 ?        00:00:00 ps -elf

Saya pernah menemukan perilaku ini sebelumnya, tetapi saya tidak dapat menemukan referensi yang lebih baik selain jawaban AskUbuntu ini.

Terkait:Apa perbedaan antara titik koma dan ampersand ganda &&?

perilaku membunuh

Sejak pkill -f asdf || true bukan perintah sederhana (ini adalah daftar perintah), pengoptimalan di atas tidak dapat terjadi sehingga ketika Anda menjalankan ssh [email protected] "pkill -f asdf || true" , sshd garpu proses dan eksekutif bash -c "pkill -f asdf || true" .

Seperti yang ditunjukkan oleh jawaban ctx, pkill tidak akan mematikan prosesnya sendiri. Namun, itu akan matikan proses lain yang baris perintahnya cocok dengan -f pola. bash -c perintah cocok dengan pola ini sehingga menghentikan proses ini – induknya sendiri (seperti yang terjadi).

Server SSH kemudian melihat bahwa proses shell yang dimulai untuk menjalankan perintah jarak jauh dimatikan secara tidak terduga sehingga melaporkan kesalahan ke klien SSH.


Linux
  1. Perintah sshpass:Otentikasi Kata Sandi Non-interaktif dengan SSH

  2. Nama pengguna dan kata sandi di baris perintah dengan sshfs

  3. SSH - Cara memasukkan perintah -t di file ~/.ssh/config

  1. Perintah Nohup dengan Contoh

  2. Perintah JQ di Linux dengan Contoh

  3. Bagaimana Cara Membunuh Baris Perintah Chromium Melalui Ssh?

  1. Lewati firewall Linux Anda dengan SSH melalui HTTP

  2. Mengirim kata sandi melalui SSH atau SCP dengan subprocess.Popen

  3. SSH dengan authorized_keys ke sistem Ubuntu dengan homedir terenkripsi?