Avec pratiquement n'importe quel shell:
printf '{ PS4=\${$(($#-$x))}; } 2>&3; 2>&1\n%.0s' |
x=LINENO+1 sh -sx "$@" 3>/dev/null
Et vous n'avez pas besoin d'utiliser de sous-coquilles. Par exemple:
set -x a b c
{ last= PS4=\${last:=\${$#}}; set +x; } 2>/dev/null
echo "$last"
... impressions ...
c
Et voici une fonction shell qui peut définir aliaspour vous un shell qui affichera les arguments en avant ou en arrière:
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
Il ne tente pas de stocker les valeurs littérales des arguments, mais il place plutôt une chaîne comme celle-ci dans args alias:
:;printf    "%.$(($??${#*}:0))s%.$((!$??${#*}:0))s\n" \
            "$1" "${3}" "${2}"  "${2}" "${3}"  "${1}"
... et ne stocke donc que les références aux paramètres en avant et en arrière. Il stockera jusqu'à un décompte tel qu'il lui est donné comme argument. Et donc ce qui précède a aliasété généré comme:
tofro 3
printfLe comportement de 'est affecté en fonction de la valeur de retour de la commande précédente - qui est toujours :la commande null, et donc généralement true. printfsautera la moitié de ses arguments à chaque impression - ce qui, par défaut, affichera les arguments du plus petit au plus grand. Cependant, si vous le faites simplement:
! args
... il les imprime à l'envers.
Étant donné que l'alias ne stocke aucune valeur littérale, sa valeur reste statique pendant que les arguments réels peuvent changer, mais il en référencera toujours autant qu'il le pourrait. Par exemple:
set one two three
tofro 3
args; ! args
shift; args; ! args
... qui imprime ...
one
two
three
three
two
one
two
three
three
two
Mais la réinitialisation de l'alias peut se faire comme:
tofro 2
args; ! args
... et donc ça imprime ...
two
three
three
two
               
              
argcar ils sont commandés correctement et non en sens inverse. À l'usage deexpr, je suis limité à utiliser la norme uniquement.