bash menambahkan tanda kutip tunggal ekstra

12

Saya memiliki masalah dalam mengeksekusi skrip saya.
Ketika menjalankannya dalam mode debug (bash -x), saya dapat melihat bahwa bash menambahkan tanda kutip tambahan. Karenanya skrip saya gagal.

Ini di dalam skrip saya:

testvar="\"sudo /home/pi/shared/blink.sh 27 off\""
ssh -n -q -q -o BatchMode=yes -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ConnectTimeout=5 $1 ${testvar}

Ini hasilnya:

ssh -n -q -q -o BatchMode=yes -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ConnectTimeout=5 192.168.42.105 '"sudo' /home/pi/shared/blink.sh 27 'off"'
pengguna2452585
sumber

Jawaban:

7

Bash menampilkan tanda kutip tunggal sehingga menunjukkan perintah yang sintaks inputnya valid. Itu tidak menjalankan perintah yang berisi tanda kutip tunggal ini dalam parameter ke sshperintah.

ssh  '"sudo' /home/pi/shared/blink.sh 27 'off"'

memberitahu Anda bahwa 4 parameter terakhir dari perintah ssh adalah "sudo, /home/pi/shared/blink.sh, 27dan off".

Pada host jarak jauh, daemon ssh menggabungkan kata-kata dari perintah dengan spasi sebagai pemisah, sehingga perintah jarak jauh yang Anda jalankan adalah

"sudo /home/pi/shared/blink.sh 27 off"

Upaya ini untuk mengeksekusi perintah yang namanya sudo /home/pi/shared/blink.sh 27 off, yang tentu saja tidak ada.

Hapus tanda kutip ganda dari definisi Anda tentang testvar.

Tidak masalah di sini, tetapi mungkin penting dalam kasus Anda yang sebenarnya: alih-alih ${testvar}, tulis "$testvar"(atau "${testvar}"jika Anda mau, tetapi kurung kurawal opsional). Selalu beri tanda kutip ganda di sekitar substitusi variabel kecuali Anda tahu mengapa Anda harus mengabaikannya. "$testvar"memperluas ke nilai variabel testvar, sedangkan $testvarketika tidak dalam tanda kutip ganda memperlakukan nilai testvarsebagai daftar pola glob yang dipisahkan oleh spasi.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
3

Saya pikir Anda harus menggunakan:

testvar="sudo /home/pi/shared/blink.sh 27 off"
ssh -n -q -q -o BatchMode=yes -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ConnectTimeout=5 $1 "${testvar}"

Ini bekerja untuk saya:

$ bash -x -c 'testvar="la la la"; echo "${testvar}"'
+ testvar='la la la'
+ echo 'la la la'
la la la

Tetapi jika saya menulis yang sama seperti yang Anda lakukan, saya mendapatkan hasil yang salah yang sama:

$ bash -x -c 'testvar="\"la la la\""; echo ${testvar}'
+ testvar='"la la la"'
+ echo '"la' la 'la"'
"la la la"
Radu Rădeanu
sumber
Kutipan sangat penting karena mereka adalah mekanisme shell untuk mengelompokkan beberapa kata bersama untuk membentuk argumen tunggal.
glenn jackman
2

Shell membagi nilai variabel menjadi kata-kata. Buat tanda kutip ganda untuk mencegah pemisahan. Lihat perbedaannya:

t='"a b c"'
set -xv
echo $t
echo "$t"
choroba
sumber