Документация по ОС FreeBSD Суббота, 20.04.2024, 02:15
Приветствую Вас Гость | RSS
Меню сайта

Категории каталога
Shell [40]

Главная » Статьи » Программирование » Shell

Ловушки bash [2010]
Программирование на shell в общем и на bash в частности богато своими нюансами, которые, зачастую, упускаются из вида. В результате мы имеем проблемы на очевидных, вообщем-то, операциях. И как результат, зачастую, бывает "а ну его, этот баш! Перепишу на php/perl/python/ruby/etc”
Эта статья написана для обсуждения и путей решения нескольких самых часто встречающихся "камней преткновения” при программировании на bash. Я лично очень полюбил программировать на bash в последнее время и хочу поделиться кусочком знаний с вами :)

1. for i in `ls *.mp3`

Знакомо? :) Если в имени файла встретится пробел, то все ваши усилия будут напрасны. Каждая из составляющих имени попадет в отдельную итерацию.

 for i in `ls *.mp3`; do # Неверно!
    some command $i      # Неверно!
 done

Не получится и "закавычить” вывод ls

 for i in "`ls *.mp3`"; do # Неверно!
 ...

В этом случае ВЕСЬ вывод ls будет рассматриваться в контексте одной итерации. Это немного не то, чего хотелось бы добиться :) Решение есть

for i in *.mp3; do  # Надо делать вот так и...
   some command "$i" # ...во втором пункте мы рассмотрим и это "узкое" место.
 done

2. cp $file $target

Если в $file или $target окажутся пробелы, то вас ждет разочарование :)
Выход не менее очевиден

 cp "$file" "$target"

3. Имена файлов, начинающиеся с дефисов

Всем известно, что параметры многих команд начинаются с дефиса -. В том случае, если с дефиса начинается имя файла, то оно будет ошибочно воспринято как параметр и вы получите ошибку. В лучшем случае.
Одно из решений - поместить перед именами передаваемых фалов два дефиса --. Это сигнализирует команде (например cp) о том, что список параметров закончен и дальше идут аргументы:

 cp -- "$file" "$target"

Но более элегантным решением, все-таки, будет цикл (причем с указанием каталога в пути к файлу):

 for i in ./*.mp3; do
   cp "$i" /target
   ...

В этом случае аргумент, начинающийся с дефиса, будет передан как ./-foo.mp3 и все сработает нормально.

4. [ $foo = "bar” ]

В bash вам необходимо заботиться о своих переменных. Иначе получите кучу ошибок :) Пример из заголовка выдаст ошибку в двух случаях:
Если переменная, переданная в [ не объявлена или пустая, то команда [ "увидит” выражение

[ $foo = "bar" ]
как

[ = "bar" ]

и вы получите ошибку unary operator expected (ожидается унарный оператор). Так как оператор = бинарный, то [ будет несколько шокирована :)
Если в $foo содержаться пробелы, то сравнение также будет некорректным

[ multiple words here = "bar" ]

И если вам это может показаться нормальным, то для [ это довольно неожиданно :)
Более корректно будет записать выражение как

 [ "$foo" = bar ] # Все отлично

но, опять-таки, выполучите ошибку, если текст в переменной начинается с -
В bash есть ключевое слово [[, которое является расширением старой команды test, также известной как [ и это решение всех подобных проблем :)

[[ $foo = bar ]] # Правильно

В случае с использованием [[ ]] вам не надо заключать переменную в кавычки, так как эта конструкция корректно обрабатывает и пустые переменные, и переменные, содержащие пробелы, и переменные, значение которых начинается с дефиса.
Также вам может встретиться вот такой вариант:

[ x"$foo" = xbar ]

x"$foo" - это хак для старых версий шелла, в которых вы вынуждены использовать [. И чтобы позаботиться о значении переменных, наичнающихся с дефиса, то можно использовать вот такую конструкцию.
А если одна из сторон сравниваемого выражения константа, то просто поместите переменную в правую часть :) [ не обращает внимания на то, что находится справа

[ bar = "$foo" ]

Только левая часть выражения требует вашего особого внимания, на случай значения, начинающегося с дефиса.

Продолжение следует :)


Источник: http://boombick.org/blog/posts/94
Категория: Shell | Добавил: oleg (10.05.2010) | Автор: Андрей Синицын aka boombick
Просмотров: 752 | Рейтинг: 0.0/0 |
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа

Beastie

Друзья сайта

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
links

Copyright MyCorp © 2024