Bash: подстановка переменной в строке в кавычках выглядит как-то из сумеречной зоны - PullRequest
0 голосов
/ 12 июля 2011

У меня есть скрипт bash, который читает, по сути, вывод telnet (на самом деле socat в сокет домена unix).

while read -r LINE; do
    if [ "$USER_DATA_FLAG" == "true" ]; then   #Evaluates to false for the moment
        ...
    else
        printf "%s\n" "Variable> $LINE" >>$DEBUG_LOG
        printf "%s\n" "Line  xxxxz $LINE yxxxxx" >>$DEBUG_LOG
        ...
    fi
done

Это дает следующий непонятный вывод:

Variable> >INFO:OpenVPN Management Interface Version 1 -- type 'help' for more info
yxxxxxxxxz >INFO:OpenVPN Management Interface Version 1 -- type 'help' for more info
Variable> OpenVPN CLIENT LIST
yxxxxxxxxz OpenVPN CLIENT LIST

Первый оператор printf работает отлично и показывает именно то, что я ожидаю, основываясь на моем опыте работы с терминалом. Но второе выражение printf сходит с ума, меняет порядок некоторых символов и печатает $ LINE совершенно не в том месте!

Ответы [ 2 ]

3 голосов
/ 12 июля 2011

$LINE содержит \r, что возвращает курсор назад к столбцу 1. Используйте подстановку параметра или tr, чтобы удалить его.

$ foo=$'1\r23'
$ echo "$foo"
23
$ echo "${foo/$'\r'/}"
123
2 голосов
/ 12 июля 2011

Это немного побродит.Первое, что я заметил, было следующее:

printf "%s\n" "Variable> $LINE" >>$DEBUG_LOG

И я сразу же подумал: «Это код на Си».В программировании оболочки printf является несколько странным инструментом, который иногда полезен, в отличие от printf в C, который является первым, чего вы достигаете, когда печатаете что-то.Попробуйте вместо этого:

echo "Variable> $LINE" >>$DEBUG_LOG

Другая проблема потенциально связана с telnet .Если вы проанализируете вывод telnet в оболочке, вы получите несколько символов, которые вам не нужны - например, возврат каретки.Значение по умолчанию IFS для bash равно <space><tab><newline>, которое НЕ будет перехватывать возврат каретки, а возврат каретки будет связываться с расположением символов в вашем терминале.

В идеале вы должны получить правильноеклиент Telnet и использовать его не в интерактивном режиме.Однако, в крайнем случае, вы можете сделать это:

while tr -d '\r' | read -r LINE; do
    ...

Это приведет к удалению возвратов каретки - но все равно может быть другой мусор telnet, включая команды WILL / WONT / DO / DONT иNUL байтов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...