bash test выдает «echo: команда не найдена» - PullRequest
6 голосов
/ 21 марта 2011

Хорошо, что-то смешное происходит внезапно. Этот тест

for i in `cat /mnt/usb/liste.txt `; do [ -f /mnt/usb/lsdvd.xml/$i ] || echo $i; done

раньше работал нормально (для каждой записи в файле liste.txt попробуйте найти соответствующий каталог, напечатайте имя, если оно не найдено) и использовал для получения имен отсутствующих каталогов. Теперь эта команда дает

 echo: command not found
 echo: command not found
 echo: command not found
(...)

Я пытался использовать [[...]] и «test» вместо «[..]», но безрезультатно.

Есть идеи, что могло случиться с моим любимым человеком, пока я не смотрел :)?

Спасибо, Christian.

Редактировать (установить -x вывод):

(...)
+ for i in '`cat /mnt/usb/liste.txt`'
+ '[' -f /mnt/usb/lsdvd.xml/THE_GHOST_WRITER.lsdvd.xml ']'
+ for i in '`cat /mnt/usb/liste.txt`'
+ '[' -f /mnt/usb/lsdvd.xml/THE_IMAGINARIUM_OF_DOCTOR_PARNASSUS.lsdvd.xml ']'
+ for i in '`cat /mnt/usb/liste.txt`'
+ '[' -f /mnt/usb/lsdvd.xml/THE_INFORMANT.lsdvd.xml ']'
+ for i in '`cat /mnt/usb/liste.txt`'
+ '[' -f /mnt/usb/lsdvd.xml/THE_INTERNATIONAL.lsdvd.xml ']'
+ for i in '`cat /mnt/usb/liste.txt`'
+ '[' -f /mnt/usb/lsdvd.xml/THE_MEN_WHO_STARE_AT_GOATS.lsdvd.xml ']'
+ for i in '`cat /mnt/usb/liste.txt`'
+ '[' -f /mnt/usb/lsdvd.xml/THE_OTHER_MAN.lsdvd.xml ']'
+ for i in '`cat /mnt/usb/liste.txt`'
+ '[' -f /mnt/usb/lsdvd.xml/THE_QUEEN.lsdvd.xml ']'
+ for i in '`cat /mnt/usb/liste.txt`'
+ '[' -f /mnt/usb/lsdvd.xml/THE_READER.lsdvd.xml ']'
+ for i in '`cat /mnt/usb/liste.txt`'
+ '[' -f /mnt/usb/lsdvd.xml/THE_REBOUND.lsdvd.xml ']'
+ $'\302\240echo' THE_REBOUND
+ '[' -x /usr/lib/command-not-found ']'
+ /usr/bin/python /usr/lib/command-not-found -- $'\302\240echo'
 echo: command not found
+ return 127
(...)

Ответы [ 4 ]

17 голосов
/ 22 марта 2011

Если вы посмотрите внимательно, вы увидите, что он печатает:

 echo: command not found

с начальным пробелом, а не:

echo: command not found

set -x делает это намного понятнее при печати:

$'\302\240echo' THE_REBOUND

0302 0240 является восьмеричным UTF-8 для неразрывного пробела .

Попробуйте удалить пробел между | и echo и введите обычный пробел.


Скорее всего, файл был отредактирован на Mac, где можно случайно ввести неразрывный пробел, если вы нажмете Option одновременно с Пробел .

Если вы используете Vim, вы можете сделать неразрывные пробелы более очевидными, используя опцию listchars . Например:

set listchars+=nbsp:% list

См. . В Vim выделены подозрительные символы , чтобы узнать больше идей.

В Linux неразрывным пробелом является Составить Пробел Пробел или Ctrl + Shift + u a 0 , так что вы, вероятно, не наберете это случайно.


Для всех, кто хочет, можно вручную преобразовать восьмеричные байты в UTF-8, используя таблицу UTF-8 из статьи Википедии об UTF-8.

Но самый простой способ, который я нашел, это использовать Python:

>>> import unicodedata
>>> unicodedata.name('\302\240'.decode('utf-8'))
'NO-BREAK SPACE'
3 голосов
/ 22 марта 2011

Редактировать: приведенный ниже код все еще в порядке, но проблема, вероятно, в $'\302\240echo': Кажется, в вашем текстовом файле неизвестные символы .Попробуйте удалить пару символов перед эхо, а затем введите их снова.

Это может быть проблема , цитирующая .Кроме того, вы можете сэкономить время, избегая бесполезного использования cat:

while IFS= read -r; do [ -f "/mnt/usb/lsdvd.xml/$REPLY" ] || echo "$REPLY"; done < /mnt/usb/liste.txt
1 голос
/ 21 марта 2011

Что происходит, когда вы просто запускаете:

for i in `cat /mnt/usb/liste.txt `; do
    echo $i
done

С одной стороны, замечаете ли вы что-нибудь ненормальное в именах файлов (пробелы, новые строки, специальные символы и т. Д.)? Если это так, вам нужно будет указать имя файла в кавычках, чтобы оболочка не интерпретировала его.

Также попробуйте использовать обычный оператор if вместо логического ИЛИ:

for i in `cat /mnt/usb/liste.txt `; do
    if [ ! -f /mnt/usb/lsdvd.xml/$i ]; then
        echo $i
    fi
done
0 голосов
/ 22 марта 2011

Работает для меня:

for f in $(< d2.lst); do [ -f ./d2/$f ] || echo $f ; done

Только мои собственные имена файлов, каталоги и предложенная конструкция $ (...) вместо обратных галочек и с <вместо cat.</p>

Возможно перевод строки DOS / Windows в вашем списке?Просмотрите его с помощью less.

...