Как вы используете PIPESTATUS, тройник и /bin/sh вместе?

Когда я бегу

curl | tee test.txt; echo ${PIPESTATUS[0]}

Я правильно вижу

curl: попробуйте 'curl --help' или 'curl --manual' для получения дополнительной информации

2

Но когда я пытаюсь запустить точно такую ​​же команду, используя '/bin/sh':

sh -c "curl | tee test.txt; echo \${PIPESTATUS[0]}"

я получил

curl: попробуйте 'curl --help' или 'curl --manual' для получения дополнительной информации

sh: 1: плохая замена

Как мы можем решить Bad substitution проблема, пожалуйста?

3 ответа

Решение

Вы решаете это, не используя sh,

PIPESTATUS переменная конкретно, а ${var[idx]} Синтаксис массива в целом - это особенности, специфичные для оболочки Bash. Они не существуют в POSIX sh, и даже оболочки, у которых есть массивы, могут использовать другой синтаксис.

Так получилось, что некоторые дистрибутивы Linux символически /bin/sh в Баш. Однако в других дистрибутивах это символическая ссылка на Debian Almquist Shell. Оба совместимы со скриптами POSIX sh, но только Bash принимает ${PIPESTATUS[…]} синтаксис.

Так что, если вы хотите использовать его, запустите bash -c "…" вместо.

Обходной путь для '/bin/sh' или busybox

status=0
eval ` { ls /dontexists || echo status="$?"; } | tee /dev/null`
echo "# status=${status}"

Трассировка:

busybox sh ~/bin/test.sh 
+ status=0
+ ls /dontexists
+ tee /dev/null
ls: /dontexists: No such file or directory
+ echo status=1
+ eval status=1
+ status=1
+ echo # status=1
# status=1

Также 'bash -c', кажется, имеет проблему с ним при вызове из tcsh:

bash -c "curl | tee test.txt; echo \${PIPESTATUS[0]}"

PIPESTATUS: неопределенная переменная.

Это работает для меня из tcsh:

bash -c 'curl | tee test.txt; echo ${PIPESTATUS[0]}'

curl: попробуйте 'curl --help' или 'curl --manual' для получения дополнительной информации
2

GNU bash, версия 4.2.25(1)-релиз (x86_64-pc-linux-gnu)
вызывается из tcsh 6.17.06

Другие вопросы по тегам