คลาสสิกบอร์นเชลล์ได้รับการสนับสนุนและทุบตีและเปลือกกรยังคงสนับสนุนเป็น-kตัวเลือก เมื่อมีผลบังคับใช้ddตัวเลือกคำสั่ง '-like ' ใด ๆ ที่ใดก็ได้บนบรรทัดคำสั่งจะถูกแปลงเป็นตัวแปรสภาพแวดล้อมที่ส่งไปยังคำสั่งโดยอัตโนมัติ:
$ set -k
$ echo a=1 b=2 c=3
$
มันค่อนข้างยากที่จะเชื่อว่าพวกเขาเป็นตัวแปรสภาพแวดล้อม ใช้งานได้สำหรับฉัน:
$ 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
$
ครั้งแรกenv | grepแสดงให้เห็นถึงไม่มีตัวแปรสภาพแวดล้อมด้วยอักษรตัวเล็กกรณีเดียว ครั้งแรกbashแสดงให้เห็นว่าไม่มีข้อโต้แย้งที่ส่งผ่านไปยังสคริปต์ที่ดำเนินการผ่าน-cและสภาพแวดล้อมที่มีตัวแปรตัวอักษรสามตัว set +kยกเลิก-kและแสดงให้เห็นว่าคำสั่งเดียวกันขณะนี้ได้ข้อโต้แย้งผ่านไป (สิ่งa=1นั้นได้รับการปฏิบัติเหมือน$0สคริปต์; คุณสามารถพิสูจน์ได้ว่าด้วยการสะท้อนที่เหมาะสม)
นี้ประสบความสำเร็จในสิ่งที่คำถามที่ถาม - ที่พิมพ์ควรจะเป็นเช่นเดียวกับการพิมพ์./script.sh a=1 b=2a=1 b=2 ./script.sh
โปรดระวังว่าคุณประสบปัญหาหากคุณลองใช้เทคนิคเช่นนี้ในสคริปต์:
if [ -z "$already_invoked_with_minus_k" ]
then set -k; exec "$0" "$@" already_invoked_with_minus_k=1
fi
การ"$@"ปฏิบัติต่อคำต่อคำ; มันไม่ได้วิเคราะห์อีกครั้งเพื่อค้นหาตัวแปรสไตล์การมอบหมาย (ทั้งในbashและksh) ฉันเหนื่อย:
#!/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
และalready_invoked_with_minus_kตัวแปรสภาพแวดล้อมเท่านั้นที่ถูกตั้งค่าในexec'd script