Saya memiliki if
pernyataan untuk menghitung file dan menghapus semua kecuali tiga file terbaru. Tapi saya ingin menjalankan perintah ini dari jarak jauh. Bagaimana saya bisa bergabung ssh
dengan suatu if
kondisi?
Saya mencoba ini tetapi tidak berhasil.
#!/bin/bash
ssh -t test@192.168.94.139 "cd /var/www/test.com/backup ;
if [ $(ls | wc -l) -lt 3 ]
then
echo "Less"
else [ $(ls -t *.tgz|awk 'NR >3'|xargs rm -f) ]
echo "deleted"
fi"
Kesalahan yang saya dapatkan:
ls: tidak dapat mengakses * .tgz: Tidak ada file atau direktori tersebut
command-line
bash
ssh
Janith
sumber
sumber
$(
)
dari perintah dieksekusi oleh shell lokal sebelum bahkan memulaissh
perintah. Itu benar baik ketika$(
)
berdiri sendiri maupun ketika itu tertutup oleh"
s. Namun jika$(
)
di dalam'
s itu tidak akan dieksekusi oleh shell lokal.Jawaban:
CATATAN: sebenarnya ada dua lapisan untuk pertanyaan di sini. Salah satunya adalah 'Saya ingin menjalankan tugas non-sepele pada server jauh yang dapat diakses melalui SSH'. Yang lain adalah 'Saya sedang mencoba memberikan string yang kompleks ke sebuah perintah, dan argumennya akhirnya berbeda dari yang saya maksudkan.' Saya menjawab pertanyaan tingkat rendah tanpa membahas apakah pendekatan yang digunakan adalah "benar" (nyaman, tidak rentan kesalahan, aman, dll.) Untuk menyelesaikan yang tingkat tinggi. Seperti yang ditunjukkan oleh jawaban dan komentar lain, sangat mungkin tidak.
Baris perintah Anda sebagian besar benar; Anda hanya perlu mengubah sedikit penawaran.
Masalah utama adalah bahwa string yang dikutip ganda diperluas oleh shell lokal Anda, dan
$(...)
bagian - bagian tersebut akan dievaluasi pada sistem lokal Anda. Untuk meneruskannya ke sistem jarak jauh, Anda harus melampirkan script dalam tanda kutip tunggal.Anda juga memiliki beberapa tanda kutip yang tertanam. Dalam naskah asli Anda, ada argumen untuk keduanya
echo
; jika Anda mengubah kutipan luar menjadi kutipan tunggal, itu akan menjadi skrip awk. Ini secara efektif menghasilkan tanda kutip yang dihilangkan, yang tidak menggangguecho
huruf s, tetapi akan mengacaukan skrip awk, karena tanda yang lebih besar dari itu akan menjadi pengalihan output. Jadi setelah Anda mengubah tanda kutip luar menjadi tanda kutip tunggal, ubah tanda kutip menjadi dua.Ini adalah skrip Anda dengan kutipan tetap. Script mungkin memiliki masalah lain, saya baru saja memperbaiki sintaks.
sumber
/var/www/test.com/backup
variabel yang disebut "BACKUPDEST" dancd $BACKUPDEST
dapatkah Anda memberi tahu saya cara melakukan ini?BACKUPDEST
? Jika itu terjadi di sisi jarak jauh, cukup sertakan dalam skrip secara normal. Jika Anda ingin menyetelnya secara lokal (mis. Menghitungnya dalam skrip lokal, atau meneruskannya sebagai argumen baris perintah), Anda dapat mengubah baris pertama menjadi mis."cd $BACKUPDEST"' ;
- shell memperluas bagian yang dikutip ganda, membuat yang dikutip tunggal bagian utuh, menggabungkan keduanya dan meneruskan hasilnya sebagai argumen terakhirssh
."cd '$BACKUPDEST'"' ;
jika path dalam variabel itu berisi beberapa keanehan (misalnya spasi). Sekali lagi: hanya mengatakan bahwa itu bisa dilakukan dengan cara ini, bukan berarti harus dilakukan dengan cara ini.Ya, Anda dapat menjalankan skrip yang rumit melalui
ssh
Contoh ini menggunakan dokumen bash di sini untuk menghasilkan string perintah. Dalam kasus apa pun, melewatkan skrip melalui ssh adalah kesalahan, karena penawaran dan pelepasan variabel sulit (ingat backslash sebelum perintah). Jika skrip menjadi terlalu rumit, lebih baik menyalinnya melalui
scp
dan kemudian menjalankannya pada host target.Saya tidak mencoba memperbaiki skrip Anda , tetapi berikut ini adalah contoh cara penghitungan dan penghapusan host jarak jauh:
Ini
ls -t *.tgz
tidak akan berfungsi, karena globbing hanya terjadi pada sistem lokal. Juga menggunakanls
untuk menghitung file bukan ide yang baik, karena juga mengembalikan entri seperti.
,..
dan direktori.sumber
syntax error near unexpected token elif'
,elif [ $(ls -t |awk 'NR >3'|xargs rm -f) ]; then'
;
hilang dalam pernyataan jika kepalan itu. Tapi saya tidak memperbaiki skrip Anda! Ada banyak lagi masalah misalnyals *.tgz
$(...)
di dalam string yang dikutip ganda, sehingga shell lokal mengevaluasinya. Melarikannya\$(...)
seperti yang Anda tunjukkan pada contoh pertama, atau menggunakan tanda kutip tunggal di sekitar keseluruhan skrip, mencegah shell lokal untuk memperluasnya, sehingga ia dikirim ke sistem jarak jauh, itu diperluas oleh shell jauh, dan skrip berfungsi sebagaimana dimaksud.printf
untuk memperluas variabel - itu masih akan lebih mudah untuk dikelola daripada mencoba keluar dari semua variabel shell di seluruh. Juga, itu akan menghindari keharusan menggunakancat
hanya untuk menangkap dokumen di sini menjadi variabel!Saya pikir seluruh hal mengutip yang rumit ini adalah bukti yang cukup untuk tidak menggunakannya tetapi menggunakan skrip. Jika Anda ingin menghindari beberapa
ssh
koneksi, pipa skrip ke host lain dan biarkan dijalankan di sana dalam satu perintah:File lokal, katakan
myscript.sh
:Kemudian:
Atau (menghindari penggunaan kucing yang tidak berguna ):
Ini mem-pipe script lokal
myscript.sh
ke sisi yang jauh di mana ia diarahkan ke file (sementara)/tmp/ms.sh
, dieksekusi, dan akhirnya dihapus.Catatan: Saya tidak memeriksa kesalahan naskah asli tetapi hanya ingin menunjukkan ide. Tidak ada kutipan rawan kesalahan diperlukan dan semua perintah dalam skrip dieksekusi di sisi jarak jauh.
sumber
ssh user@host bash <myscript.sh
.mktemp
atau sesuatu yang serupa amannya.Saya lebih suka menempatkan script pada contoh jarak jauh dan hanya menjalankannya melalui ssh, tapi di sini adalah saran saya bagaimana ini bisa dilakukan dengan cara yang Anda inginkan:
Catatan:
-lt
digantikan oleh-le
.eval
- membangun perintah dengan menggabungkan argumen.\"
di dalam$COMMAND{1..3}
ekspresi, tetapi saya memutuskan untuk menambahkannya.sumber