Чому мені потрібно використовувати CD "$ @" замість CD "$ 1" під час написання обгортки для CD?


25

В іншому місці я бачив CD-функцію, як показано нижче:

cd()
{
 builtin cd "$@"
}

чому рекомендується використовувати $@замість $1?

Я створив тестовий каталог "r st" і назвав скрипт, що містить цю функцію, і він працював у будь-якому випадку

$ . cdtest.sh "r st"

але $ . cdtest.sh r stне вдалося, чи я використовував, "$@"чи"$1"


1
cd "$*"також не буде правильно працювати з більш ніж 1 арг.
GoFundMonica - codidact.org

Відповіді:


57

Тому що, на думку bash(1), cdбере аргументи

   cd [-L|[-P [-e]] [-@]] [dir]
          Change  the  current  directory to dir.  if dir is not supplied,
          ...

таким чином, каталог насправді може бути не в $1тому, що натомість може бути такою опцією, як -Lчи інший прапор.

Наскільки це погано?

$ cd -L /var/tmp
$ pwd
/var/tmp
$ cd() { builtin cd "$1"; }
$ cd -L /var/tmp
$ pwd
/home/jhqdoe
$ 

Все може піти дуже помилково, якщо ви опинитесь не там, де очікуєте використання cd "$1"


19

Використання "$@"передасть усі аргументи туди, cdде як $1передасть лише перший аргумент.

У ваших прикладах

$ . cdtest.sh "r st"

завжди працює так, як ви передаєте лише один аргумент, але якщо ви повинні також передавати прапор

$ . cdtest.sh -L "r st"

Тоді тільки "$@"буде виконано правильно, де "$1"розшириться до cd -Lвтрати каталогу повністю.

Однак

$ . cdtest.sh r st

Виходить з ладу в обох випадках, оскільки ви передаєте два параметри в CD, rі stце не є дійсним способом виконання cd. Параметри розділені пробілами, які повинні бути цитованими (як у вашому першому прикладі) або уникнутими ( r\ st), щоб їх розглядати як один аргумент.

У випадку з компакт-диском дуже часто зустрічаються прапори, і ви не можете переходити в декілька каталогів, тому ви не побачите різниці у використанні реального світу "$1"або "$@"для CD-дисків. Але для інших команд , які ви будете помічати різницю , так що краще практика , щоб завжди використовувати , "$@"коли ви хочете створити функцію - оболонку або сценарій , як це.


14

Існує також випадок, коли немає аргументів:

$ cd /tmp; cd; pwd
/home/muru
$ cd_func() { builtin cd "$1"; }
$ cd_func /tmp; cd_func; pwd
/tmp

cdбез жодних аргументів зміни в домашній каталог. Без жодних аргументів "$@"розширюється до нічого, але "$1"розширюється до порожнього рядка. Вони різні:

$ args() { for i in "$@"; do echo "|$i|"; done; }
$ args
$ args ""
||

Дещо не пов'язане між собою, але: я нарешті розумію, чому нульовий аргумент cd- це добра справа. Це викликає помилку замість того, щоб перейти на домашній каталог. У деяких інших команд, зокрема rsync, перший нульовий аргумент викликає несподівану поведінку (включає поточний каталог у джерелах передачі).
Джо

4

Аргументи до bash-сценарію обмежені простором. $ 1 - перший аргумент. У ваших прикладах ...

У прикладі 1, $ 1 - рядок "r st" ... у другому прикладі $ 1 - це рядок символу 'r' ...

$ @ - це всі аргументи.

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