Печать печати только одной строкой

Я пытаюсь получить вывод env в переменной оболочки и распечатать его.

 #!/bin/sh ENV_BEFORE=$(env) printf $ENV_BEFORE 

В результате печатается одна переменная из env выхода.

При использовании echo вместо printf выводится весь вывод, но без новых строк.

Что мне здесь не хватает?

  • печатать несколько слов, разделенных пробелом
  • Предотвращение наручных цветов
  • printf тыс. разделитель не работает на MacBook
  • Печать переменной с обратной косой чертой в тире
  • Еще одна синтаксическая ошибка около неожиданного токена `('
  • Порядок печати?
  • bash предотвращает прерывание printf другой printf
  • Десятичное шестнадцатеричное преобразование, работающее в Linux, но не в Unix
  • 2 Solutions collect form web for “Печать печати только одной строкой”

    Проблема в том, что вы не цитируете переменную $ENV . Как объясняется в man bash :

    Закрывающиеся символы в двойных кавычках сохраняют буквальное значение всех символов внутри кавычек, за исключением $, `, \, и, когда включено расширение истории,!. Символы $ и `сохраняют свое особое значение в двойных кавычках. Обратная косая черта сохраняет свое особое значение только тогда, когда следует один из следующих символов: $, `,", \ или .

    Итак, включение такой последовательности, как \n в двойных кавычках, сохраняет свое значение. Вот почему, когда не цитируется, \n является просто нормальным n :

     $ printf \n n$ 

    Хотя при цитировании:

     $ printf "\n" $ 

    Необязательная переменная в bash вызывает оператор split + glob. Это означает, что переменная разделяется на пробелы (или независимо от того, какая специальная переменная $IFS была установлена), и каждое результирующее слово используется в качестве глоба (оно будет расширяться, чтобы соответствовать любым совпадающим именам файлов). Ваша проблема связана с «разделенной» частью этого.

    Чтобы проиллюстрировать, давайте возьмем более простую многострочную переменную:

     $ var=$(printf "foo\nbar\n") 

    Теперь, используя функцию set -x отладки оболочки, вы можете точно увидеть, что происходит:

     $ echo $var + echo foo bar foo bar $ echo "$var" + echo 'foo bar' foo bar 

    Как вы можете видеть выше, echo $var (unquoted) подвергает $var разбиению + glob, поэтому получается две отдельные строки: foo и bar . Новая линия была съедена расколом + глобусом. Когда переменная была указана, она не была подвергнута split + glob, новая строка сохранена и, поскольку она цитируется, также интерпретируется правильно, распечатывается реклама.

    Следующая проблема заключается в том, что printf не похож на echo . Он не просто печатает все, что вы ему даете, он ожидает строку формата. Например, printf "color:%s" "green" будет печатать color:green потому что %s будет заменен green .

    Он также игнорирует любой ввод, который не может вписаться в строку формата, которую он дал. Итак, если вы запустите printf foo bar , printf будет обрабатывать foo как строку и строку формата в качестве переменной, которую он должен отформатировать. Поскольку нет %s или эквивалента, который должен быть заменен на bar , bar игнорируется, и только foo печатается:

     $ printf $var + printf foo bar foo 

    Вот что произошло, когда вы запустили printf $ENV_BEFORE . Поскольку переменная не была процитирована, split glob эффективно заменил новые строки пробелами, а printf только напечатал первое «слово», которое он увидел.

    Чтобы сделать это правильно, используйте строки форматирования и всегда указывайте свои переменные:

     printf '%s\n' "$ENV_BEFORE" 

    printf (в отличие от echo ) по умолчанию не печатает новую строку, вам нужно явно указать:

     printf "${ENV_BEFORE}\n" 

    Или лучше:

     printf '%s\n' "$ENV_BEFORE" 

    После того, как @don_crissti правильно указал в комментарии, и после того, как я снова прочитал вопрос, я думаю, что ваше дело отличается от предыдущего.

    В вашем случае проблема заключается в том, что вы не $ENV_BEFORE переменную $ENV_BEFORE .

    Вот поведение printf и echo если вы не указали переменную:

    • printf :

      1. Без цитаты и любого спецификатора формата он будет печатать только первое слово

      2. С цитатой и без какого-либо спецификатора формата он будет рассматривать что-либо в расширении, имеющем % качестве спецификатора формата, и может задушить

      3. Без цитаты и с спецификатором формата он будет подвержен расщеплению слов и расширению пути, следовательно, приведет к неожиданному результату, поскольку любое значение IFS станет пространством на выходе

      4. С помощью спецификатора цитат и формата вы получите желаемый результат, т. Е. Разложение слов и расширение пути не будут выполняться при расширении.

    • echo :

      1. Без цитаты расширение переменной будет подвержено расщеплению слов и расширению пути, поэтому вы не получите желаемый результат

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

    Linux и Unix - лучшая ОС в мире.