Я довольно новичок в скриптах Bash. У меня есть «тестовый скрипт», который я использовал в качестве основы для более продвинутого / полезного скрипта:
#!/bin/bash
files=$1
for a in $files
do
echo "$a"
done
Когда я вызываю это без кавычек, он просто берет один файл в каталоге:
testscript *.txt
Но когда я вызываю его с кавычками, он работает правильно и выбирает все текстовые файлы:
testscript '*.txt'
Что здесь происходит?
bash
shell-script
gornvix
источник
источник
for a in "$@"; do
(илиfor a; do
) в вашем скрипте, таким образом оставляя глобализацию на внешнюю оболочку, чтобы не пропустить кавычки.Ответы:
Когда вы вызываете программу
тогда ваша оболочка выполняет расширение и обрабатывает все значения. Так что это может, фактически, назвать вашу программу как
Теперь ваша программа только смотрит
$1
и работает только дальшеfile1.txt
.Цитируя в командной строке, вы передаете буквальную строку
*.txt
в скрипт, и это то, что хранится в$1
. Вашfor
цикл затем расширяет его.Обычно вы будете использовать,
"$@"
а не$1
в сценариях, как это.Это «уловка» для людей, пришедших из сценариев CMD, где командная оболочка не выполняет глобализацию (как известно) и всегда пропускает буквальную строку.
источник
"$@"
(в отличие от$@
или$1
$2
$3
) приведет к тому, что каждое имя файла будет заключено в кавычки"file1.txt"
"file2.txt"
и т. Д.file1.txt
Это бессмысленно, но если это такmy file.txt
, цитирование имеет решающее значение для предотвращения оболочки анализ, чтобы превратить его в два имени файла, одно имяmy
и одно имяfile.txt
. Всегда цитируйте пользовательский ввод и расширение глобуса, чтобы вы не были очень несчастны в один прекрасный день.Без кавычек оболочка раскрывается
*.txt
перед вызовом скрипта, поэтому раскрывается$1
только первый файл. На данный момент всеtxt
файлы являются аргументами вашего сценария (при условии, что их не слишком много).С кавычками эта строка передается без расширения в сценарий, который затем позволяет
for
выполнить расширение, как вы и надеялись.источник