POSIX równoważnik sh dla Bash's printf% q
Przypuśćmy, że mam#!/bin/sh
skrypt, który może przyjmować różne parametry pozycyjne, z których niektóre mogą zawierać spacje, albo oba rodzaje cytatów itp. Chcę iterować"$@"
i dla każdego argumentu albo przetworzyć go jakoś natychmiast, albo zapisać na później. Na końcu skryptu chcę go uruchomić (być możeexec
) inny proces, przekazując niektóre z tych parametrów z nienaruszonymi wszystkimi znakami specjalnymi.
Gdybym nie przetwarzał parametrów,othercmd "$@"
działa dobrze, ale muszę wyciągnąć niektóre parametry i trochę je przetworzyć.
Gdybym mógł założyć Bash, mógłbym użyćprintf %q
obliczyć cytowane wersje argumentów, które mógłbymeval
później, ale to nie zadziałałoby np. Dash Ubuntu (/bin/sh
).
Czy istnieje odpowiednikprintf %q
które można napisać zwykłym skryptem powłoki Bourne'a, używając tylko wbudowanych i narzędzi zdefiniowanych przez POSIX, powiedzmy jako funkcję, którą mogę skopiować do skryptu?
Na przykład skrypt próbującyls
jego argumenty w odwrotnej kolejności:
#!/bin/sh
args=
for arg in "$@"
do
args="'$arg' $args"
done
eval "ls $args"
działa w wielu przypadkach:
$ ./handle goodbye "cruel world"
ls: cannot access cruel world: No such file or directory
ls: cannot access goodbye: No such file or directory
ale nie kiedy'
jest używany:
$ ./handle goodbye "cruel'st world"
./handle: 1: eval: Syntax error: Unterminated quoted string
a poniższe działa dobrze, ale opiera się na Bash:
#!/bin/bash
args=
for arg in "$@"
do
printf -v argq '%q' "$arg"
args="$argq $args"
done
eval "ls $args"