set-u penggunaan tidak berfungsi seperti yang diharapkan

12

Saya belajar cara efisien menggunakan berbagai setopsi dalam skrip saya dan menemukan set -uyang tampaknya sempurna untuk keluar dari skrip saya jika variabel tidak diset dengan benar (mis. Menghapus pengguna). Menurut halaman manual , set -udan set -emelakukan hal berikut ...

-e  Exit immediately if a command exits with a non-zero status.
-u  Treat unset variables as an error when substituting.

Saya membuat skrip pengujian untuk menguji fungsi ini, tetapi tampaknya tidak berfungsi seperti yang diharapkan. Mungkin seseorang bisa lebih menjelaskan masalah saya kepada saya dan di mana saya salah menafsirkan? Script tes di bawah ini. Terima kasih.

set -e
set -u
testing="This works"
echo $?
echo ${testing}
testing2=
echo $?
echo ${testing2}
testing3="This should not appear"
echo $?
echo ${testing3}

Saya mengharapkan skrip untuk menampilkan 0 dan "Ini berfungsi" , dan kemudian gagal karena ${testing2}tidak diatur.

Sebagai gantinya saya ditampilkan 0 dan "Ini berfungsi" , diikuti oleh 0 dan kemudian 0 Ini seharusnya tidak muncul

Adakah yang bisa memberikan pengetahuan? Terima kasih.

Azifor
sumber
1
Jadi tindak lanjut ... apakah ada cara untuk membuat pengaturan variabel ke string nol ilegal / meningkatkan kesalahan? Saya kira tidak.
Luke Davis

Jawaban:

10

Dari "man Bash":

Parameter diatur jika telah diberi nilai. String nol adalah nilai yang valid. Setelah variabel diatur, itu mungkin tidak disetel hanya dengan menggunakan perintah bawaan yang tidak disetel.

Ketika Anda melakukannya, testing2=Anda sedang mengatur variabel ke string nol.

Ubah itu menjadi unset testing2dan coba lagi.


Dalam hal set -eini tidak membantu karena tugas tidak pernah memiliki kode keluar dari 1. Coba ini untuk melihat bahwa perintah terakhir yang dijalankan (tugas) memiliki kode keluar 0, atau baca pertanyaan ini :

$ false; a=""; echo $?
0

Dan saya juga percaya bahwa penggunaan set -e lebih merupakan masalah daripada solusi.

Apa yang mungkin mendapatkan kesalahan dengan penggunaan variabel yang tidak disetel adalah set -u:

#!/bin/bash
set -u
testing="This works"
echo ${testing}
unset testing2
echo ${testing2}
testing3="This should not appear"
echo ${testing3}

Akan menghasilkan:

$  ./script.sh
This works
./script.sh: line 9: testing2: unbound variable
Komunitas
sumber
3

testing2=set testing2variabel ke string kosong; variabel sebenarnya diatur .

Namun jika Anda menjalankan echo $testing99Bash shell interaktif (tanpa pengaturan errexit, yaitu, set -e), Anda akan mendapatkan kesalahan:

bash: testing99: unbound variable

Ke samping

Saat menguji skrip sekarang, saya menemukan bahwa shell interaktif tidak selalu keluar ketika mencoba untuk memperluas variabel yang belum ditetapkan sementara shell non-interaktif (menjalankan skrip shell) selalu keluar . Menurut halaman manual POSIX untuk set:

-u Shell harus menulis pesan ke kesalahan standar ketika mencoba memperluas variabel yang tidak disetel dan segera keluar. Shell interaktif tidak boleh keluar.

Sebuah Bash shell interaktif tidak akan keluar kecuali errexitmemiliki juga telah ditetapkan. Di sisi lain, shell dasbor interaktif tidak akan keluar - bahkan jika set -esebelumnya telah dijalankan.

Anthony Geoghegan
sumber
Jika tanda hubung tidak keluar dengan set -e; set -u; tidak disetel aa; gema $ aa, lalu dash salah.
schily
@schily Ketika saya pertama kali memperhatikan ini, saya menemukan bahwa penulis dasbor tahu lebih baik daripada saya dan bahwa mungkin ada beberapa ambiguitas dalam spesifikasi POSIX tetapi setelah memeriksa kembali pubs.opengroup.org/onlinepubs/9699919799/utilities/… , saya setuju yang terlihat seperti bug, oke.
Anthony Geoghegan
Ada aturan sederhana: ketika Korn Shell dan Bourne Shell setuju dan implementasi shell lain memiliki penyimpangan, maka shell lain berperilaku salah.
schily