|
|||||||
Частые ошибки программирования на Bash (часть 3)
Время создания: 01.03.2009 00:21
Текстовые метки: linux, unix, bash
Раздел: Компьютер - Linux - Bash - Программирование на Bash
Запись: xintrea/mytetra_syncro/master/base/0000000808/text.html на raw.github.com
|
|||||||
|
|||||||
Частые ошибки программирования на Bash (Часть 3) 22. echo "Hello World!" Проблема в том, что в интерактивной оболочке Bash эта команда вызовет ошибку: bash: !": event not found Это происходит потому, что при установках по умолчанию Bash выполняет подстановку истории команд в стиле csh с использованием восклицательного знака. В скриптах такой проблемы нет, только в интерактивной оболочке. Очевидное решение здесь не работает: $ echo "hi\!" hi\! Можно заключить эту строку в одинарные кавычки: echo 'Hello World!' Но самое подходящее решение здесь — временно выключить параметр histexpand. Это можно сделать командой set +H или set +o histexpand: set +H echo "Hello World!" Почему же тогда всегда не пользоваться одиночными кавычками? Представьте, что вы хотите получить информацию об mp3-файлах: mp3info -t "Don't Let It Show" ... mp3info -t "Ah! Leah!" ... Одинарные кавычки здесь не подходят, поскольку названия песен содержат апострофы в названиях, а использование двойных кавычек приведёт к проблеме с подстановкой истории команд (а если бы в именах файлов ещё и двойные ковычки содержались, получилось бы вообще черте что). Поскольку лично я (Greg Wooledge, автор текста) никогда не использую подстановку истории команд, я просто поместил команду set +H в свой .bashrc. Но это вопрос привычки и каждый решает для себя сам. 23. for arg in $* В Bash'е, так же, как и в других оболочках семейства Bourne shell, есть специальный синтаксис для работы с позиционными параметрами по очереди, но $* и $@ не совсем то, что вам нужно: после подстановки параметров они становятся списком слов, переданных в аргументах, а не списком параметров по отдельности. Вот правильный синтаксис: for arg in "$@" Или просто: for arg for arg соответствует for arg in "$@". Заключенная в двойные кавычки переменная "$@" — это специальная уличная магия, благодаря которой каждый аргумент командной строки заключается в двойные кавычки, так что он выглядит как отдельное слово. Другими словами, "$@" преобразуется в список "$1" "$2" "$3" и т.д. Этот трюк подойдёт в большинстве случаев. Рассмотрим пример: #!/bin/bash # неправильно for x in $*; do echo "parameter: '$x'" done Этот код напечатает: $ ./myscript 'arg 1' arg2 arg3 parameter: 'arg' parameter: '1' parameter: 'arg2' parameter: 'arg3' Вот как это должно выглядеть: #!/bin/bash # правильно! for x in "$@"; do echo "parameter: '$x'" done $ ./myscript 'arg 1' arg2 arg3 parameter: 'arg 1' parameter: 'arg2' parameter: 'arg3' 24. function foo() В некоторых шеллах это работает, но не во всех. Никогда не комбинируйте ключевое слово function со скобками (), определяя функцию. Некоторые версии bash позволяют одновременно использовать и function, и (), но ни в одной другой оболочке так делать нельзя. Некоторые интерпретаторы, правда, воспримут function foo, но для максимальной совместимости лучше использовать: foo() { ... } 25. echo "~" Замена тильды (tilde expansion) происходит только когда символ ~ не окружён кавычками. В этом примере echo выведет ~ в stdout, вместо того, чтобы вывести пользовательский домашний каталог. Экранирование переменных с путями, которые должны быть выражены относительно домашнего каталога, должно производиться с использованием $HOME вместо ~. "~/dir with spaces" # "~/dir with spaces" ~"/dir with spaces" # "~/dir with spaces" ~/"dir with spaces" # "/home/my photos/dir with spaces" "$HOME/dir with spaces" # "/home/my photos/dir with spaces" 26. local varname=$(command) Определяя локальную переменную в функции, local сама работает как команда. Иногда это может непонятным образом взаимодействовать с остатком строки. Например, если в следующей команде вы хотите получить код возврата ($?) подставленной команды, вы его не получите: код возврата команды local его перекрывает. Поэтому эти команды лучше разделять: local varname varname=$(command) rc=$? |
|||||||
Так же в этом разделе:
|
|||||||
|
|||||||
|