Чому для виклику цього сценарію Bash потрібні лапки для аргументів файлів?


13

Я зовсім новачок сценаріїв Баша. У мене є "тестовий сценарій", який я використав як основу для більш просунутого / корисного сценарію:

#!/bin/bash
files=$1
for a in $files
do
    echo "$a"
done

Коли я закликаю це без жодних лапок, він просто збирає один файл у каталозі:

testscript *.txt

Але коли я називаю це цитатами, він працює правильно і вибирає всі текстові файли:

testscript '*.txt'

Що тут відбувається?


Щоб бути дуже, дуже зрозумілим, правильний спосіб виправити це - запустити for a in "$@"; do(або for a; do) у своєму сценарії, тим самим залишаючи глобус до зовнішньої оболонки, а не залишати без лапок.
Чарльз Даффі


Це добре варто подивитися. guide.bash.academy
vascowhite

Відповіді:


29

Коли ви викликаєте програму

testscript *.txt

тоді ваша оболонка виконує розширення та опрацьовує всі значення. Тож це може ефективно називати вашу програму як

testscript file1.txt file2.txt file3.txt file4.txt

Тепер ваша програма лише дивиться $1і так працює лише file1.txt.

Цитуючи в командному рядку, ви передаєте буквальний рядок *.txtдо сценарію, і саме в цьому зберігається $1. forПотім ваш цикл розгортає його.

Зазвичай ви використовуєте, "$@"а не $1в таких сценаріях.

Це "готча" для людей, що надходять із скриптів CMD, де командна оболонка не робить глобулювання (як відомо) і завжди передає буквальний рядок.


6
Просто для уточнення (для інших осіб, ніж автор вищезгаданої відповіді), використання "$@"(на відміну від $@або $1 $2 $3) призведе до цитування кожного імені файлу "file1.txt" "file2.txt"тощо. file1.txtЦе безглуздо, але якщо у вас є my file.txt, цитування є критичним для запобігання оболонки синтаксичний аналіз, щоб перетворити його на дві назви файлів, одну з названих myта одну з названих file.txt. Завжди цитуйте вклад користувача та глобальне розширення, щоб ви не були дуже нещасними в якийсь день.
Сет Робертсон

2
І це не просто теоретично - Mac OS X одного разу постачався із сценарієм оновлення, який не належним чином цитував аргументи, а в деяких випадках видаляв жорсткі диски людей.
пухнаста

2
@fluffy, у вас є посилання на це?
Wildcard

@Wildcard На жаль, я не можу знайти жодних статей про це, але це було великою новиною в світі технологій, коли це сталося. Я хочу сказати, що це було в 2003/2004 роках або в наступних періодах, тоді, коли Apple все ще почала дистрибуцію UNIX.
пухнастий

1
@wildcard Ах, знайшов! xlr8yourmac.com/OSX/itunes2_erased_drives.html - винуватцем цього був сценарій оновлення iTunes.
пухнастий

7

Без лапок оболонка розширюється *.txtперед тим, як викликати скрипт, тому розширюється $1лише перший файл. Усі txtфайли є аргументами до вашого сценарію в той момент (якщо їх не надто багато).

З цитатами цей рядок передається без розширення в сценарій, який потім дозволяє forробити розширення, як ви сподіваєтесь.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.