Разница между 'ls' и 'echo $(ls)'

Библиотеки ncurses созданы для различных конфигураций (см. страницу руководства ).

Сообщение Mutt о версии содержит много деталей, но разработчики упустили из виду, была ли обнаружена версия ncurses для расширенных символов или нет.

Если вы установите пакет libncursesw5-dev и переконфигурируете, сценарий покажет что-то вроде этого:

checking for initscr... no
checking for waddnwstr in -lncurses... no
checking for waddnwstr in -lncursesw... yes
checking for initscr in -lncursesw... yes
checking for tgetent in -ltinfo... yes
checking ncursesw/ncurses.h usability... yes
checking ncursesw/ncurses.h presence... yes
checking for ncursesw/ncurses.h... yes
checking for start_color declaration... yes
checking for typeahead declaration... yes
checking for bkgdset declaration... yes
checking for curs_set declaration... yes
checking for meta declaration... yes
checking for use_default_colors declaration... yes
checking for resizeterm declaration... yes
checking for use_extended_names... yes

и единственный способ узнать, какая библиотека использовалась, будет использовать ldd :

linux-vdso.so.1 =>  (0x00007ffd72ba4000)
libncursesw.so.5 => /lib/x86_64-linux-gnu/libncursesw.so.5 (0x00007f4f2131d000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f4f210f4000)
libssl.so.1.0.0 => /lib/x86_64-linux-gnu/libssl.so.1.0.0 (0x00007f4f20e8a000)
libcrypto.so.1.0.0 => /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 (0x00007f4f20a46000)
libidn.so.11 => /usr/lib/x86_64-linux-gnu/libidn.so.11 (0x00007f4f20813000)
libdb-5.3.so => /usr/lib/x86_64-linux-gnu/libdb-5.3.so (0x00007f4f20465000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4f2009c000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f4f1fe98000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f4f1fc7a000)
/lib64/ld-linux-x86-64.so.2 (0x0000562212af9000)

или (используя мой externs скрипт для фильтрации результатов) с нм :

$ externs mutt |grep NCURSES
beep@@NCURSESW_5.1.20000708
cbreak@@NCURSES_TINFO_5.0.19991023
clearok@@NCURSESW_5.1.20000708
curs_set@@NCURSES_TINFO_5.0.19991023
curses_version@@NCURSES_TINFO_5.0.19991023
endwin@@NCURSESW_5.1.20000708
flushinp@@NCURSES_TINFO_5.0.19991023
has_colors@@NCURSESW_5.1.20000708
init_pair@@NCURSESW_5.1.20000708
initscr@@NCURSESW_5.1.20000708
isendwin@@NCURSESW_5.1.20000708
key_defined@@NCURSES_TINFO_5.4.20040208
keypad@@NCURSES_TINFO_5.0.19991023
meta@@NCURSES_TINFO_5.0.19991023
noecho@@NCURSESW_5.1.20000708
printw@@NCURSESW_5.1.20000708
resizeterm@@NCURSESW_5.1.20000708
scrollok@@NCURSESW_5.1.20000708
start_color@@NCURSESW_5.1.20000708
tigetflag@@NCURSES_TINFO_5.0.19991023
tigetstr@@NCURSES_TINFO_5.0.19991023
typeahead@@NCURSES_TINFO_5.0.19991023
use_default_colors@@NCURSESW_5.1.20000708
use_extended_names@@NCURSES_TINFO_5.1.20000708
vwprintw@@NCURSESW_5.1.20000708
wadd_wch@@NCURSESW_5.3.20021019
waddch@@NCURSESW_5.1.20000708
waddnstr@@NCURSESW_5.1.20000708
wbkgdset@@NCURSESW_5.1.20000708
wclear@@NCURSESW_5.1.20000708
wclrtobot@@NCURSESW_5.1.20000708
wclrtoeol@@NCURSESW_5.1.20000708
wgetch@@NCURSESW_5.1.20000708
wmove@@NCURSESW_5.1.20000708
wrefresh@@NCURSESW_5.1.20000708
wtimeout@@NCURSES_TINFO_5.0.19991023

27
17.05.2016, 21:56
2 ответа

Когда вы запускаете эту команду:

ls

терминал отображает вывод LS .

Когда вы запускаете эту команду:

echo $(ls)

оболочка захватывает вывод $ (ls) и выполняет разбиение слов на нем. При использовании по умолчанию IFS это означает, что все последовательности пробелов, , включая символов новой строки, заменяются одним пробелом. Поэтому вывод echo $ (ls) отображается в одной строке.

Для более подробного обсуждения разбиения слов см. FAQ Грега .

Подавление разбиения слов

Оболочка не выполняет разбиение слов на строках в кавычках. Таким образом, вы можете подавить разделение слов и сохранить многострочный вывод с помощью:

echo "$(ls)"

ls и многострочного вывода

. Вы могли заметить, что ls иногда печатает более одного файла в строке:

$ ls
file1  file2  file3  file4  file5  file6

Это значение по умолчанию, когда вывод ls поступает на терминал. Когда вывод не поступает напрямую на терминал, ls изменяет свое значение по умолчанию на один файл на строку:

$ echo "$(ls)"
file1
file2
file3
file4
file5
file6

Такое поведение задокументировано в man ls .

Еще одна тонкость: подстановка команд и завершающие символы новой строки

$ (...) - это подстановка команд , и оболочка удаляет завершающие символы новой строки из вывода подстановки команд . Обычно это не заметно, потому что по умолчанию echo добавляет одну новую строку в конец своего вывода. Итак, если вы потеряете одну новую строку с конца $ (...) и получите одну из echo , изменений не будет. Однако, если вывод вашей команды заканчивается двумя или более символами новой строки, а echo возвращает только один, в вашем выводе будет отсутствовать один или несколько символов новой строки. В качестве примера мы можем использовать printf для генерации завершающих символов новой строки. Обратите внимание, что обе следующие команды, несмотря на разное количество символов новой строки, производят один и тот же вывод в виде одной пустой строки:

$ echo "$(printf "\n")"

$ echo "$(printf "\n\n\n\n\n")"

$ 

Такое поведение задокументировано в man bash .

Еще один сюрприз: двукратное расширение имени пути

Создадим три файла:

$ touch 'file?' file1 file2

Обратите внимание на разницу между ls file? и echo $ (ls file?) :

$ ls file?
file?  file1  file2
$ echo $(ls file?)
file? file1 file2 file1 file2

В случае echo $ (ls file?) глобальный файл file? раскрывается дважды , в результате чего имена файлов file1 и file2 , чтобы дважды появиться в выводе. Это связано с тем, что, как указывает Джеффикинс, раскрытие имени пути сначала выполняется оболочкой перед запуском ls , а затем еще раз перед запуском echo .

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

$ echo "$(ls file?)"
file?
file1
file2
77
27.01.2020, 19:39

ls знает, посылает ли он вывод на терминал или нет.

Выполнение ls в командной строке приведет к записи на ваш псевдотерминал. Перенаправление вывода ls обычно не идет на псевдотерминал, а ls будет форматировать вывод по-другому.

0
27.01.2020, 19:39

Теги

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