echo выводит параметр -e в скриптах bash.Как я могу предотвратить это? - PullRequest
25 голосов
/ 14 декабря 2010

Я прочитал справочные страницы по echo, и он говорит мне, что параметр -e позволит экранированному символу, такому как экранированный n для новой строки, иметь свое особое значение. Когда я набираю команду

$ echo -e 'foo\nbar'

в интерактивную оболочку bash, я получаю ожидаемый результат:

foo
bar

Но когда я использую эту же команду (я пробовал эту символьную команду для символа в качестве контрольного примера), я получаю следующий вывод:

-e foo
 bar

Это как если бы echo интерпретировал -e как параметр (потому что символ новой строки по-прежнему отображается), но также интерпретирует -e как строку для эха. Что тут происходит? Как я могу предотвратить появление -e?

Ответы [ 4 ]

33 голосов
/ 14 декабря 2010

Вам необходимо использовать #!/bin/bash в качестве первой строки в вашем скрипте. Если вы этого не сделаете или используете #!/bin/sh, сценарий будет запускаться оболочкой Bourne, а echo не распознает параметр -e. В общем, рекомендуется, чтобы все новые сценарии использовали printf вместо echo, если важна переносимость.

В Ubuntu sh предоставляется символической ссылкой на /bin/dash.

4 голосов
/ 14 декабря 2010

Разные реализации echo ведут себя по-разному. Некоторые не принимают параметры (то есть просто выводят -e, как вы описали) и автоматически интерпретируют escape-последовательности в своих параметрах. Некоторые принимают флаги и не интерпретируют escape-символы, если не указан флаг -e. Некоторые принимают флаги и интерпретируют различные escape-последовательности в зависимости от того, был ли передан флаг -e. Некоторые заставят вас рвать на себе волосы, если вы попытаетесь заставить их вести себя предсказуемо ... о, подождите, вот и все.

То, что вы, вероятно, видите здесь, - это разница между версией echo, встроенной в bash против /bin/echo или, возможно, по сравнению со встроенной оболочкой какой-либо другой оболочки. Это меня поразило, когда Mac OS X v10.5 поставлялась со встроенной в echo bash, которая отражала флаги, в отличие от того, что ожидали все мои скрипты ...

В любом случае, есть решение: используйте printf. Он всегда интерпретирует escape-последовательности в своем первом аргументе (строка формата). Проблемы заключаются в том, что он не добавляет автоматически новую строку (поэтому вы должны помнить, что делаете это явно), а также интерпретирует последовательности % в своем первом аргументе (в конце концов, это строка формата). Как правило, вы хотите поместить все элементы форматирования в строку формата, а затем поместить переменные строки в остальные аргументы, чтобы вы могли контролировать, как они интерпретируются, в каком формате % вы используете для интерполяции их в выходные данные. Некоторые примеры:

printf "foo\nbar\n"      # this does what you're trying to do in the example
printf "%s\n" "$var"     # behaves like 'echo "$var"', except escapes will never be interpreted
printf "%b\n" "$var"     # behaves like 'echo "$var"', except escapes will always be interpreted
printf "%b\n" "foo\nbar" # also does your example
1 голос
/ 14 декабря 2010

Используйте

псевдоним echo / usr / bin / echo

заставить 'echo' вызывать coreutils 'echo, который интерпретирует параметр -e'

0 голосов
/ 21 марта 2017

Попробуйте это:

import subprocess

def bash_command(cmd):
    subprocess.Popen(['/bin/bash', '-c', cmd])

code="abcde"
// you can use echo options such as -e
bash_command('echo -e "'+code+'"')

Источник: http://www.saltycrane.com/blog/2011/04/how-use-bash-shell-python-subprocess-instead-binsh/

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