Почему форматирование байта printf завершается ошибкой при выполнении под `тире `?

Я установил XV на более старую версию Cygwin -X около 5 лет назад, и xv не появлялся в окнах startx. Мне бы rxvt -родной запустить, а уж потом подойдёт. На более новом компьютере с Windows 10 я установил Cygwin -X, но родной rxvt -больше не доступен (или еще нет? )в последней версии Cygwin -X. Мне не удалось открыть окна xv. Так что, похоже, на данный момент xv не может работать на Cygwin -X, по крайней мере, не так, как есть. XV все еще можно получить у Джона Брэдли (просто погуглите xv john bradley )за небольшую плату и он будет работать на других Unix -подобных ОС, возможно, с некоторой настройкой, потому что, как уже упоминалось, программное обеспечение было написано 24 года назад.

3
01.01.2021, 01:38
2 ответа

При выполнении

$ sh -c printf '\x30'

Я понял

printf: usage: printf [-v var] format [arguments]

, который уже дает ценный намек на то, что printfне получает ожидаемых параметров. Решение состоит в том, чтобы убедиться, что параметр команды представляет собой одну строку, а не несколько параметров, заключив его в кавычки. И, конечно, добавление новой строки для удобства чтения не помешает:

$ sh -c "printf '\x30\n'"
0
1
18.03.2021, 22:39

Реализация printfв некоторых оболочках (bash, ksh, zsh, по крайней мере; даже в режиме эмуляции sh)понимает \xHHкак шестнадцатеричное число HH. Однако это расширение стандартной printfспецификации .

Стандарт POSIX требует, чтобы printfраспознавал \0ddd, где ddd— нулевое, одно-, двух- или трехзначное восьмеричное число.

Оболочка, которая заменяет /bin/shв вашей системе, скорее всего,dash(или, что менее вероятно, yash), которая понимает восьмеричную (, как и все стандартные оболочки ), но не понимает шестнадцатеричную, при использовании с printf.

Шестнадцатеричное число 30 равно 60 в восьмеричном, поэтому

$ sh -c 'printf "%b\n" "$1"' sh '\060'
0

Или, если вы не хотите передавать восьмеричное число в качестве аргумента, а вместо этого хотите использовать его как статический литерал:

$ sh -c 'printf "\060\n"'
0

(Обратите внимание на разницу здесь с оператором sh -cв вашем вопросе :весь оператор printf, включая его аргументы, является частью строки, заданной в качестве аргумента опции -утилиты sh-cвариант. Я предполагаю, что в вашем вопросе есть простая опечатка.)

Причина, по которой вашему сценарию удалось правильно напечатать ноль, заключается либо в том, что у вас была строка#!-в сценарии, которая указывала на исполняемый файл оболочки bash, либо у вас не было такой строки вообще. и вместо этого запустил скрипт из интерактивной оболочки bash. Оболочка bashпри выполнении сценария оболочки без строки #!будет использовать bashдля его запуска (см. Какой интерпретатор оболочки запускает сценарий без шебанга? подробнее об этой детали ).

При запуске скрипта с явным интерпретатором, как в sh myScript.sh, строка #!, если она есть, будет проигнорирована.

5
18.03.2021, 22:39

Теги

Похожие вопросы