Saya mencoba untuk membangun skrip shell yang menerima berbagai opsi dan getoptssepertinya solusi yang baik karena dapat menangani pemesanan variabel opsi dan argumen (saya pikir!).
Saya hanya akan menggunakan opsi pendek dan setiap opsi pendek akan membutuhkan nilai yang sesuai, misalnya: ./command.sh -a arga -g argg -b argbtetapi saya ingin mengizinkan opsi dimasukkan dalam urutan non-spesifik, seperti cara kebanyakan orang terbiasa bekerja dengan perintah shell .
Poin lainnya adalah bahwa saya ingin melakukan pemeriksaan nilai argumen opsi saya sendiri, idealnya dalam casepernyataan. Alasan untuk ini adalah bahwa pengujian saya :)dalam casepernyataan saya telah menghasilkan hasil yang tidak konsisten (mungkin karena kurangnya pemahaman di pihak saya).
Sebagai contoh:
#!/bin/bash
OPTIND=1 # Reset if getopts used previously
if (($# == 0)); then
echo "Usage"
exit 2
fi
while getopts ":h:u:p:d:" opt; do
case "$opt" in
h)
MYSQL_HOST=$OPTARG
;;
u)
MYSQL_USER=$OPTARG
;;
p)
MYSQL_PASS=$OPTARG
;;
d)
BACKUP_DIR=$OPTARG
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 2;;
:)
echo "Option -$OPTARG requires an argument" >&2
exit 2;;
esac
done
shift $((OPTIND-1))
echo "MYSQL_HOST='$MYSQL_HOST' MYSQL_USER='$MYSQL_USER' MYSQL_PASS='$MYSQL_PASS' BACKUP_DIR='$BACKUP_DIR' Additionals: $@"
Gagal untuk kejadian seperti ini ... ./command.sh -d -h
Ketika saya ingin flag -d sebagai membutuhkan argumen tapi saya mendapatkan nilai -d=-hyang bukan yang saya butuhkan.
Jadi saya pikir akan lebih mudah untuk menjalankan validasi saya sendiri dalam laporan kasus untuk memastikan bahwa setiap opsi diatur dan ditetapkan hanya sekali.
Saya mencoba melakukan yang berikut tetapi if [ ! "$MYSQL_HOST" ]; thenblok saya tidak terpicu.
OPTIND=1 # Reset if getopts used previously
if (($# == 0)); then
echo "Usage"
exit 2
fi
while getopts ":h:u:p:d:" opt; do
case "$opt" in
h)
MYSQL_HOST=$OPTARG
if [ ! "$MYSQL_HOST" ]; then
echo "host not set"
exit 2
fi
;;
u)
MYSQL_USER=$OPTARG
if [ ! "$MYSQL_USER" ]; then
echo "username not set"
exit 2
fi
;;
p)
MYSQL_PASS=$OPTARG
if [ ! "$MYSQL_PASS" ]; then
echo "password not set"
exit 2
fi
;;
d)
BACKUP_DIR=$OPTARG
if [ ! "$BACKUP_DIR" ]; then
echo "backup dir not set"
exit 2
fi
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 2;;
#:)
# echo "Option -$opt requires an argument" >&2
# exit 2;;
esac
done
shift $((OPTIND-1))
echo "MYSQL_HOST='$MYSQL_HOST' MYSQL_USER='$MYSQL_USER' MYSQL_PASS='$MYSQL_PASS' BACKUP_DIR='$BACKUP_DIR' Additionals: $@"
Apakah ada alasan bahwa saya tidak dapat memeriksa apakah OPTARGpanjang nol dari dalam getopts ... while ... case?
Apa cara yang lebih baik untuk menjalankan validasi argumen saya sendiri getoptsdalam kasus di mana saya tidak ingin bergantung pada :). Lakukan validasi argumen saya di luar while ... case ... esac?
Lalu saya bisa berakhir dengan nilai argumen -ddll dan tidak menangkap opsi yang hilang.
whileloop menjalankan opsi. Ini adalah metode yang telah saya gunakan seolah-olah itu verbose dibandingkan dengan yang lain, sangat jelas apa yang terjadi dalam naskah. Dan pemeliharaan oleh orang lain adalah penting dalam hal ini.