संक्षिप्त उत्तर: उपयोग"$@"
(दोहरे उद्धरण चिह्नों पर ध्यान दें)। अन्य रूप बहुत कम उपयोगी हैं।
"$@"
एक अजीब वाक्यविन्यास है। यह अलग-अलग क्षेत्रों के रूप में, सभी स्थितिगत मापदंडों द्वारा प्रतिस्थापित किया जाता है। यदि कोई स्थितिगत पैरामीटर नहीं है ( $#
0 है), तो "$@"
कुछ भी नहीं फैलता है (खाली स्ट्रिंग नहीं है, लेकिन 0 तत्वों के साथ एक सूची है), यदि एक स्थितीय पैरामीटर है, तो "$@"
इसके बराबर है "$1"
, यदि दो स्थितीय पैरामीटर हैं, तो "$@"
इसके बराबर है "$1" "$2"
, आदि।
"$@"
आपको किसी स्क्रिप्ट या फ़ंक्शन के तर्क को किसी अन्य कमांड को पास करने की अनुमति देता है। यह रैपर के लिए बहुत उपयोगी है जो पर्यावरण चर, डेटा फ़ाइल तैयार करना, आदि उन्हीं तर्कों और विकल्पों के साथ एक कमांड को कॉल करने से पहले करता है, जिनके साथ रैपर को बुलाया गया था।
उदाहरण के लिए, निम्न फ़ंक्शन आउटपुट को फ़िल्टर करता है cvs -nq update
। आउटपुट फ़िल्टरिंग और रिटर्न स्टेटस (जो कि grep
इसके बजाय है cvs
) के अलावा, cvssm
कुछ तर्कों पर कॉल cvs -nq update
करना इन तर्कों के साथ कॉल करने जैसा व्यवहार करता है।
cvssm () { cvs -nq update "$@" | egrep -v '^[?A]'; }
"$@"
स्थितिगत मापदंडों की सूची में विस्तार करता है। सरणियों का समर्थन करने वाले गोले में, सरणी के तत्वों की सूची का विस्तार करने के लिए एक समान सिंटैक्स है: "${array[@]}"
(ब्रेसिज़ को ज़श को छोड़कर अनिवार्य है)। फिर से, दोहरे उद्धरण कुछ भ्रामक हैं: वे सरणी तत्वों के क्षेत्र विभाजन और पैटर्न पीढ़ी के खिलाफ रक्षा करते हैं, लेकिन प्रत्येक सरणी तत्व अपने क्षेत्र में समाप्त होता है।
कुछ प्राचीन गोले में यकीनन एक बग था: जब कोई स्थैतिक तर्क नहीं थे, "$@"
एक खाली मैदान वाले एक क्षेत्र में विस्तारित किया गया था, न कि किसी क्षेत्र में। इसने वर्कअराउंड${1+"$@"}
( पर्ल दस्तावेज के माध्यम से प्रसिद्ध ) का नेतृत्व किया । वास्तविक बॉर्न शेल और OSF1 कार्यान्वयन के केवल पुराने संस्करण प्रभावित हैं, इसके आधुनिक संगत प्रतिस्थापन (राख, क्श, बाश, ...) में से कोई भी नहीं हैं। /bin/sh
21 वीं सदी में जारी की गई किसी भी प्रणाली से प्रभावित नहीं है, जो मुझे पता है (जब तक आप Tru64 रखरखाव रिलीज की गिनती नहीं करते हैं, और यहां तक कि /usr/xpg4/bin/sh
सुरक्षित है तो केवल #!/bin/sh
स्क्रिप्ट प्रभावित होती है, #!/usr/bin/env sh
स्क्रिप्ट नहीं जब तक कि आपका PATH POSIX अनुपालन के लिए सेट नहीं हो जाता) । संक्षेप में, यह एक ऐतिहासिक किस्सा है जिसके बारे में आपको चिंता करने की आवश्यकता नहीं है।
"$*"
हमेशा एक शब्द के लिए फैलता है। इस शब्द में स्थितीय पैरामीटर हैं, जिन्हें बीच में एक स्थान के साथ समतल किया गया है। (आम तौर पर, विभाजक IFS
चर के मूल्य का पहला वर्ण है । यदि मान IFS
रिक्त स्ट्रिंग है, तो विभाजक रिक्त स्ट्रिंग है।) यदि कोई स्थितिगत पैरामीटर नहीं हैं "$*"
, तो रिक्त स्ट्रिंग है, यदि दो हैं। स्थितिगत मापदंडों और IFS
उसके डिफ़ॉल्ट मान तो "$*"
इसके बराबर है "$1 $2"
, आदि।
$@
और $*
बाहर के उद्धरण बराबर हैं। वे अलग-अलग क्षेत्रों की तरह, स्थितीय मापदंडों की सूची में विस्तार करते हैं "$@"
; लेकिन प्रत्येक परिणामी फ़ील्ड को अलग-अलग फ़ील्ड्स में विभाजित किया जाता है, जिन्हें फ़ाइल नाम वाइल्डकार्ड पैटर्न के रूप में माना जाता है, हमेशा की तरह अनक्वॉटेड चर विस्तार के साथ।
उदाहरण के लिए, यदि वर्तमान निर्देशिका में तीन फ़ाइलें हैं bar
, baz
और foo
, तब:
set -- # no positional parameters
for x in "$@"; do echo "$x"; done # prints nothing
for x in "$*"; do echo "$x"; done # prints 1 empty line
for x in $*; do echo "$x"; done # prints nothing
set -- "b* c*" "qux"
echo "$@" # prints `b* c* qux`
echo "$*" # prints `b* c* qux`
echo $* # prints `bar baz c* qux`
for x in "$@"; do echo "$x"; done # prints 2 lines: `b* c*` and `qux`
for x in "$*"; do echo "$x"; done # prints 1 lines: `b* c* qux`
for x in $*; do echo "$x"; done # prints 4 lines: `bar`, `baz`, `c*` and `qux`