Katakanlah saya memiliki skrip melakukan:
some-command "$var1" "$var2" ...
Dan, dalam hal yang var1
kosong, saya lebih suka bahwa itu diganti dengan apa pun selain string kosong, sehingga perintah yang dijalankan adalah:
some-command "$var2" ...
dan tidak:
some-command '' "$var2" ...
Apakah ada cara yang lebih sederhana daripada menguji variabel dan memasukkannya secara kondisional?
if [ -n "$1" ]; then
some-command "$var1" "$var2" ...
# or some variant using arrays to build the command
# args+=("$var1")
else
some-command "$var2" ...
fi
Apakah ada substitusi parameter daripada yang bisa diperluas ke bash, zsh, atau sejenisnya? Saya mungkin masih ingin menggunakan globbing di sisa argumen, jadi menonaktifkan itu dan menghapus tanda kutip variabel bukanlah pilihan.
bash
shell-script
zsh
variable
muru
sumber
sumber
man
halaman? (-;Jawaban:
Kerang dan Bash yang sesuai dengan posix memiliki
${parameter:+word}
:Jadi Anda bisa melakukan:
dan telah
var1
diperiksa, dan"$var1"
digunakan jika disetel dan tidak kosong (dengan aturan kutip ganda biasa). Kalau tidak, itu tidak akan berkembang. Perhatikan bahwa hanya bagian dalam yang dikutip di sini, bukan semuanya.Hal yang sama juga berfungsi di zsh. Anda harus mengulangi variabelnya, jadi itu tidak ideal, tetapi berfungsi persis seperti yang Anda inginkan.
Jika Anda ingin variabel set-tetapi-kosong diperluas ke argumen kosong, gunakan
${var1+"$var1"}
sebaliknya.sumber
word
bagiannya saja.:+
dan+
.sh
/dash
untuk skrip chokepoint potensial, jadi saya selalu menghargainya ketika seseorang menunjukkan bagaimana sesuatu mungkin terjadi tanpa menggunakan Bash.Itu yang
zsh
dilakukan secara default ketika Anda menghilangkan tanda kutip:Sebenarnya, satu-satunya alasan mengapa Anda masih membutuhkan tanda kutip di zsh di sekitar ekspansi parameter adalah untuk menghindari perilaku itu (penghapusan kosong) karena
zsh
tidak memiliki masalah lain yang memengaruhi shell lain ketika Anda tidak mengutip ekspansi parameter (pemisahan implisit + glob) .Anda dapat melakukan hal yang sama dengan cangkang mirip POSIX lain jika Anda menonaktifkan split dan glob:
Sekarang, saya berpendapat bahwa jika variabel Anda dapat memiliki nilai 0 atau 1, itu harus berupa array dan bukan variabel skalar dan gunakan:
Dan gunakan
var1=(value)
kapanvar1
mengandung satu nilai,var1=('')
kapan itu mengandung satu nilai kosong, danvar1=()
kapan itu tidak mengandung nilai.sumber
Saya mengalami ini menggunakan rsync dalam skrip bash yang memulai perintah dengan atau tanpa
-n
untuk beralih kering. Ternyata rsync dan sejumlah perintah gnu mengambil''
sebagai argumen pertama yang valid dan bertindak berbeda daripada jika tidak ada.Butuh beberapa saat untuk debug karena parameter nol hampir tidak terlihat.
Seseorang di daftar rsync menunjukkan kepada saya cara untuk menghindari masalah ini sementara juga sangat menyederhanakan pengkodean saya. Jika saya memahaminya dengan benar, ini adalah variasi dari saran terakhir @ Stéphane Chazelas.
Bangun argumen perintah Anda di sejumlah variabel terpisah. Ini dapat diatur dalam urutan atau logika apa pun yang sesuai dengan masalah.
Kemudian, pada akhirnya, gunakan variabel untuk membangun array dengan semua yang ada di tempatnya dan gunakan itu sebagai argumen untuk perintah yang sebenarnya.
Dengan cara ini, perintah hanya dikeluarkan di satu tempat dalam kode alih-alih diulang untuk setiap variasi argumen.
Variabel apa pun yang kosong hilang begitu saja menggunakan metode ini.
Saya tahu menggunakan eval sangat disukai. Saya tidak ingat semua detailnya, tetapi saya tampaknya membutuhkannya untuk menyelesaikan pekerjaan dengan cara ini - ada hubungannya dengan menangani parameter dengan ruang putih tertanam.
Contoh:
sumber