मूल रूप से किसी भी शेल के साथ:
printf '{ PS4=\${$(($#-$x))}; } 2>&3; 2>&1\n%.0s' |
x=LINENO+1 sh -sx "$@" 3>/dev/null
और आपको उप-भागों का उपयोग करने की आवश्यकता नहीं है । उदाहरण के लिए:
set -x a b c
{ last= PS4=\${last:=\${$#}}; set +x; } 2>/dev/null
echo "$last"
... प्रिंट ...
c
और यहाँ एक शेल फ़ंक्शन है जो aliasआपके लिए एक शेल सेट कर सकता है जो आगे या पीछे के तर्कों को प्रिंट करेगा:
tofro() case $1 in (*[!0-9]*|'') ! :;;(*) set "$1"
until [ "$1" -eq "$(($#-1))" ] &&
shift && alias args=":; printf \
\"%.\$((\$??\${#*}:0))s%.\$((!\$??\${#*}:0))s\n\" $* "
do [ "$#" -gt 1 ] &&
set "$@ \"\${$#}\" " '"${'"$((1+$1-$#))"'}"' ||
set "$1" '"$1" "${'"$1"'}"'
done; esac
यह किसी भी तर्क के लिए शाब्दिक मूल्यों को संग्रहीत करने का प्रयास नहीं करता है, बल्कि यह इस तरह एक स्ट्रिंग डालता है args alias:
:;printf "%.$(($??${#*}:0))s%.$((!$??${#*}:0))s\n" \
"$1" "${3}" "${2}" "${2}" "${3}" "${1}"
... और इसलिए केवल पीछे और आगे के मापदंडों को संदर्भित करता है। यह एक तर्क के रूप में दी गई गणना तक संग्रहीत करेगा। और इसलिए उपरोक्त aliasकी तरह उत्पन्न किया गया था:
tofro 3
printfपिछले कमांड के रिटर्न वैल्यू के आधार पर व्यवहार प्रभावित होता है - जो हमेशा :शून्य कमांड होता है, और इसलिए आमतौर पर सच होता है। printfहर बार अपने तर्कों के आधे हिस्से को छोड़ देता है - जो कि डिफ़ॉल्ट रूप से, सबसे छोटी संख्या से सबसे बड़ी संख्या तक छपे हुए तर्कों को प्राप्त करेगा। हालांकि, अगर आप अभी करते हैं:
! args
... यह उन्हें उल्टा छापता है।
क्योंकि उपनाम किसी भी शाब्दिक मूल्यों को संग्रहीत नहीं करता है, इसका मूल्य स्थिर रहता है जबकि वास्तविक args बदल सकता है, लेकिन यह अभी भी कई के रूप में संदर्भित करेगा। उदाहरण के लिए:
set one two three
tofro 3
args; ! args
shift; args; ! args
... जो प्रिंट करता है ...
one
two
three
three
two
one
two
three
three
two
लेकिन उपनाम को रीसेट करना जैसे किया जा सकता है:
tofro 2
args; ! args
... और इसलिए यह प्रिंट ...
two
three
three
two
argक्योंकि वे सही ढंग से आदेश दिए गए हैं और रिवर्स में नहीं। के उपयोग के लिएexpr, मैं केवल मानक का उपयोग करने के लिए सीमित हूं।