基本的にどんなシェルでも:
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
の動作は、前のコマンドの戻り値に基づいて影響を受け:
ます。これは常にnullコマンドであるため、通常はtrueです。printf
は、印刷するたびに引数の半分をスキップします。デフォルトでは、引数は最小の番号から最大の番号に出力されます。ただし、次のことを行う場合:
! 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
、標準のみを使用するように制限されています。