Shell Bourne klasik didukung, dan shell Bash dan Korn masih mendukung, sebuah -k
opsi. Ketika itu berlaku, dd
opsi perintah '-seperti' di mana saja pada baris perintah dikonversi secara otomatis menjadi variabel lingkungan yang diteruskan ke perintah:
$ set -k
$ echo a=1 b=2 c=3
$
Agak sulit untuk meyakinkan bahwa mereka adalah variabel lingkungan; menjalankan ini bekerja untuk saya:
$ set -k
$ env | grep '^[a-z]=' # No environment a, b, c
$ bash -c 'echo "Args: $*" >&2; env' a=1 b=2 c=3 | grep '^[a-z]='
Args:
a=1
b=2
c=3
$ set +k
$ bash -c 'echo "Args: $*" >&2; env' a=1 b=2 c=3 | grep '^[a-z]='
Args: b=2 c=3
$
Yang pertama env | grep
menunjukkan tidak ada variabel lingkungan dengan satu huruf kecil. Yang pertama bash
menunjukkan bahwa tidak ada argumen yang diteruskan ke skrip dieksekusi melalui -c
, dan lingkungan memang mengandung tiga variabel huruf tunggal. The set +k
membatalkan -k
, dan menunjukkan bahwa perintah yang sama sekarang memiliki argumen berlalu untuk itu. (Itu a=1
diperlakukan sebagai$0
naskah; Anda dapat membuktikannya juga, dengan gema yang sesuai.)
Ini mencapai apa yang ditanyakan oleh pertanyaan - bahwa mengetik ./script.sh a=1 b=2
harus sama dengan mengetik a=1 b=2 ./script.sh
.
Perlu diketahui bahwa Anda mengalami masalah jika Anda mencoba trik seperti ini di dalam skrip:
if [ -z "$already_invoked_with_minus_k" ]
then set -k; exec "$0" "$@" already_invoked_with_minus_k=1
fi
Ini "$@"
diperlakukan kata demi kata; itu tidak dianalisis kembali untuk menemukan variabel gaya penugasan (dalam keduanya bash
dan ksh
). Saya mencoba:
#!/bin/bash
echo "BEFORE"
echo "Arguments:"
al "$@"
echo "Environment:"
env | grep -E '^([a-z]|already_invoked_with_minus_k)='
if [ -z "$already_invoked_with_minus_k" ]
then set -k; exec "$0" "$@" already_invoked_with_minus_k=1
fi
echo "AFTER"
echo "Arguments:"
al "$@"
echo "Environment:"
env | grep -E '^([a-z]|already_invoked_with_minus_k)='
unset already_invoked_with_minus_k
dan hanya already_invoked_with_minus_k
variabel lingkungan diatur dalam exec
skrip d.