
Рассмотрим эти shell
команды
$ls
my_app newlist note
и
$echo *
my_app newlist note
и
$printf *
my_app
Первая команда ls
выведет список информации о файлах (текущая директория по умолчанию). Вторая команда echo
— это команда, которая выводит строки, переданные ей в качестве аргументов. Однако, когда я печатаю, echo *
она выводит то же самое, что и ls
.
И printf *
выдает мне только первое имя файла в качестве вывода
Почему echo
интерпретация *
такая? И почему printf
, еще более странно: с выводом только первого?
решение1
Почему echo
интерпретирует *
делать то же самое, что иls
Ответ прост. Это не так. echo
делает именно так, как вы говорите: перебирает свои аргументы и выводит их с пробелом между ними.
Так почему же мы наблюдаем такое поведение ls
?
Это потому, что оболочка заменит *
на список параметров, соответствующий всем файлам (не начинающимся с a .
(если только dotglob не включен)). Затем echo
просто делает свое дело. Эта замена glob произойдет длявсекоманды, так как это делается оболочкой, а не командой.
Ну и что printf
?
printf
это форматирование печати. Первый аргумент — это формат. Если вы делаете printf "%s " *
, то это как echo
.
Если первый файл — hello%sworld
, то вы получите:hellofile2world hellofile3world
Чтобы узнать больше
Попробуйте это. Это поможет вам понять, что происходит. (Я не предлагаю вам использовать этот код для чего-то реального. Просто используйте его для обучения).
Попробуйте cat /proc/self/cmdline * | less
— в начале будет показано, как выглядит командная строка (после того, как оболочка выполнит свою часть работы).
решение2
просто потому, что у него нет входных данных для отображения, но есть список * (всех) файлов в качестве параметра для отображения в виде строки
так просто
в то время как * является параметром, он отображает содержимое "*", поэтому список файлов