Уникнення помилок через нерозгорнуту зірочку


16

У bash я часто використовую for-петлі, такі як нижче

for file in *.type; do 
  sommecommand "$file"; 
done;

виконати операцію для відповідності всіх файлів *.type. Якщо в робочих каталогах не знайдено жодного файлу з цим закінченням, зірочка не розширюється, і зазвичай я отримаю повідомлення про помилку, в якому сказано, що деякийкоманд не знайшов файл. Я можу відразу придумати кілька способів уникнути цієї помилки. Але додавання умовного виглядає не дуже елегантно. Чи існує короткий і чистий спосіб цього досягти?

Відповіді:


20

Так, запустіть таку команду:

shopt -s nullglob

це зведе нанівець збіг, і помилка не буде викликана.

  • якщо ви хочете, щоб ця поведінка була за замовчуванням, додайте команду у свій ~/.bashrc
  • якщо ви хочете виявити нульовий глобул в оболонці POSIX, спробуйте

    for i in *.txt; do
      [ "$i" = '*.txt' ] && [ ! -e '*.txt' ] && continue
    done

Дивіться сторінку http://mywiki.wooledge.org/NullGlob


1
Зауважте, що насправді можна викликати файл *.txt. Варто перевірити, чи файл існує.
Кріс Даун

публікація відповідно відредагована.
Жилль Кінот

@ChrisDown Зверніть увагу , що той же коментар , як на вашу відповідь застосовується тут (з потенційно більш серйозними наслідками через breakзамість continue).
Стефан Хазелас

6

У bash ви можете використовувати shopt -s nullglobдля розширення до порожнього масиву, якщо немає відповідностей.

У оболонках POSIX без nullglobцієї проблеми ви можете уникнути, перевіривши, чи є ім'я файлу насправді наявним [ -e "$file" ] || [ -L "$file" ] || continueв якості першої частини вашого forциклу.


1
Зауважте, що це не буде абсолютно рівнозначним, оскільки [ -eповертає false для недоступних файлів або файлів, які є посиланнями на недоступні або існуючі файли.
Стефан Шазелас

@StephaneChazelas, нехай визнаються моменти про символьні посилання. Але що ви маєте на увазі під "недоступними файлами"? Навіть якщо я chmod 0 the_file, по- [ -e the_file ]як і раніше оцінює вірно, тому воно повинно бути що - то ще.
сумнівним

1
надіслано редагування для обробки зламаних посилань сподіваюся, що це нормально.
сумнівним

2
@dubiousjim, mkdir -p x/{a,b} && chmod 444 x && echo x/* && [ -e x/a ]. x / a недоступний, але так як x читабельний x / * розшириться.
Стефан Шазелас

@StephaneChazelas, чудово, дякую за пояснення.
сумнівним

4

Звичайна техніка для снарядів, які не мають nullglobможливості

set -- [*].type *.type
case $1$2 in
  '[*].type*.type') shift 2;;
  *) shift
esac
for file do
  cmd  -- "$file"
done

Додатковим [*].typeє покриття випадку, коли *.typeв поточному каталозі є один файл, який викликається .

Тепер, якщо ви хочете включити крапкові файли, це стає складніше .

Я вважаю, що техніку було винайдено Лаурою Ферхед на Usenet кілька років тому.


0

find . -name '*.type' -maxdepth 0 -exec somecommand "{}" ";"

Це повністю виводить forцикл і кульову оболонку з рівняння. findбуде виконувати -execкоманду один раз на матч, і якщо немає відповідностей, вона ніколи не буде виконуватися. У -maxdepth 0інструктує знайти не рекурсию в підкаталоги з ім'ям шляху-аргументу ( .в даному випадку).

Мінус полягає в тому, що він включає інший додаток, хоч і той, який присутній практично в будь-якій системі Linux там (і, мабуть, і в більшості Unixes).

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