Я не могу понять, как заставить оболочку, которая интерпретирует скрипт, «забыть», что он это делает, или скрыть диагностическую информацию, связанную со скриптом, из своих сообщений об ошибках.
Однако, хотя эта контекстная информация сохраняется через форки (в подоболочки), она не передается через execs (новым процессам оболочки).
Таким образом, за счет развилки / запуска нового процесса оболочки вы можете сделать
var=$(sh -c 'printf "1\r" > /dev/cu.usbserial' 2>&1)
который устанавливает $var
в
sh: /dev/cu.usbserial: Permission denied
Особенность sh -c
которая иногда сбивает людей с толку (особенно когда они используют ее в find … -exec sh -c "…" {} ";"
), заключается в том, что дополнительные аргументы командной строки (после -c
и команда для новая оболочка для запуска) принимаются в качестве параметров командной строки для новой оболочки, начиная с $0
. И $0
рассматривается как имя оболочки / скрипта, которое впоследствии используется новой оболочкой для префикса сообщений об ошибках.
Так,
sh -c 'echo "Mellow rhymes with $2, but nothing rhymes with $1."; printf "1\r" > /dev/cu.usbserial' \
red orange yellow
(разбит на две строки исключительно для удобства чтения)
Mellow rhymes with yellow, but nothing rhymes with orange.
red: /dev/cu.usbserial: Permission denied
Так что, если вы хотите прибегнуть к хитрому взлому, чтобы значение переменной начиналось с чего-то другого, чем sh:
или bash:
используйте
var=$(sh -c 'printf "1\r" > /dev/cu.usbserial' error 2>&1)
который устанавливает $var
в
error: /dev/cu.usbserial: Permission denied
(заставляя оболочку думать, что ее имя - error
).