Почему в echo $(cat /path/to/fileName) перечислены мои файлы и папки?

Я работаю над обработкой текста, чтобы предоставить ответ на вопрос пользователя на Au. Когда я хочу попробовать распечатать содержимое файла echo $(cat /path/to/filename), это список моих файлов и папок тоже. Но когда я пытаюсь с printf "$(cat /path/to/filename)\n" это работает хорошо.

Я попытался также сохранить его в переменную content='cat /path/to/filename' (также content=$(cat /path/to/filename), а затем распечатать echo $content, но я получаю тот же неправильный результат (список файлов и папок).

Я хочу сохранить содержимое файла в переменную и передать переменную в мой скрипт в качестве входных данных для следующей команды.

Обратите внимание, что содержимое моего файла имеет * характер в этом.

Пожалуйста, смотрите примеры:

kasiya@kasiya-pc:~$ cat ~/test
*Hello World!*
kasiya@kasiya-pc:~$ echo $(cat ~/test)
*Hello World!*
------------------------------------------------------------------------------------------------------------------------------------------------------------
kasiya@kasiya-pc:~$ cat ~/test
*
Hello World!*
kasiya@kasiya-pc:~$ echo $(cat ~/test)
Desktop Documents Downloads Music Pictures Public Templates test Videos Hello World!*
------------------------------------------------------------------------^^^^^^^^^^^^^------------------------------------------------------------------------
kasiya@kasiya-pc:~$ cat ~/test
*Hello World!
*
kasiya@kasiya-pc:~$ echo $(cat ~/test)
*Hello World! Desktop Documents Downloads Music Pictures Public Templates test Videos
^^^^^^^^^^^^^-----------------------------------------------------------------------------------------------------------------------------------------------
kasiya@kasiya-pc:~$ cat ~/test
*
Hello World!
*
kasiya@kasiya-pc:~$ echo $(cat ~/test)
Desktop Documents Downloads Music Pictures Public Templates test Videos Hello World! Desktop Documents Downloads Music Pictures Public Templates test Videos
------------------------------------------------------------------------^^^^^^^^^^^^------------------------------------------------------------------------

Фантастика

kasiya@kasiya-pc:~$ cat ~/test
*
kasiya@kasiya-pc:~$ echo $(cat ~/test)
Desktop Documents Downloads Music Pictures Public Templates test Videos

Тогда каждый * в моем файле причина, чтобы перечислить мои файлы и папки. Тогда как мне это предотвратить?

2 ответа

Решение

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

POSIX определил расширение слова как:

Порядок расширения слова должен быть следующим:

  1. Должны выполняться расширение тильды (см. Расширение тильды), расширение параметров (см. Расширение параметров), подстановка команд (см. Подстановка команд) и арифметическое расширение (см. Арифметическое расширение), начиная с конца и до конца. См. Пункт 5 в разделе "Распознавание токенов".

  2. Разделение полей (см. Разделение полей) должно выполняться на участках полей, сгенерированных на шаге 1, если IFS не равен нулю.

  3. Расширение имени пути (см. Расширение пути) должно выполняться, если не задан параметр -f.

  4. Удаление цитаты (см. Удаление цитаты) всегда должно выполняться последним.

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

echo "$(cat /path/to/fileName)"

Цитировать это:

$ echo "*" >> test
$ echo $(cat test)
bash43-001 bash43-002 bash43-003 bash43-004 bash43-005 test
$ echo "$(cat test)"
*

Как правило, всегда указывайте подстановку команд.

Голые * будет расширен в bash, если вы не выключите тряпку (set -f или же setopt noglob) или цитировать / убежать от него: "*" \*, Для вывода команды всегда лучше использовать кавычки.

Другие вопросы по тегам