Как я использую “если” команда для нескольких условий?

Лучшее решение, которое я нашел, к:

find . -delete

однако, - удаляют предикат, опасно (см. человека), и мне не нравится использовать его.

Обновление:

Мне не нравится -delete предикат, потому что это может вызвать аварию при использовании кем-то не знакомым с деталями логики находки. Например:

find . -delete -name '*.bak'  # DO NOT DO IT!!!

Кто-то может ожидать, что такой вызов удалит только '*.bak' файлы, но это - точный эквивалент find . -delete.

6
24.10.2014, 19:47
5 ответов

POSIXly можно использовать ls

if ls town-*.swf >/dev/null 2>&1 &&
   ls city-*.swf >/dev/null 2>&1 
then
  mkdir towns
fi

или короче, если условие:

if ls town-*.swf city-*.swf >/dev/null 2>&1

даже если оболочка поддерживает расширение кронштейна :

if ls {town,city}-*.swf >/dev/null 2>&1
6
27.01.2020, 20:22
if stat -t city-*.swf >/dev/null 2>&1
then
    if stat -t town-*.swf >/dev/null 2>&1
    then
       mkdir towns
    fi
fi

Как пользователь UWE указывал в комментариях, моя предыдущая команда помешает расширению дикой карты. Однако эта новая версия должна работать.

Если вам это нужно с одним , если LOOP, вы можете изменить сценарий как

if stat -t city-*.swf >/dev/null 2>&1 && stat -t town-*.swf >/dev/null 2>&1
then
     mkdir towns
fi

, если вам нужно указывать или условие вместо и условие, вы можете заменить && с || .

Тестирование

ls
city-1.swf  city-2.swf  city-3.swf  city-4.swf  city-5.swf  sc.sh  
town-1.swf  town-2.swf  town-3.swf  town-4.swf  town-5.swf

Теперь я выполняю сценарий, который называется SC.SH , а затем я мог видеть, что каталог каталог успешно создается.

Ссылки

https://stackoverflow.com/questions/2937407/test-wheather-a-glob-has-any-matches-in-bash

5
27.01.2020, 20:22

В большинстве случаев команда test ( [ ) предлагает операторы -a и -o

EXPR1 -a EXPR2 Верно, если оба expr1 и expr2 верны.
EXPR1 -o EXPR2 Верно, если верны либо expr1, либо expr2.

Но в случае возможных мультистрок вы должны использовать команду, которая может работать в условии (например, ls)

ls {town,city}-*.swf &>/dev/null && mkdir town

Можно использовать тот факт, что globbing, когда не удается найти замену, остается строкой как есть (в случае с *). Поэтому нам просто нужно проверить, находится ли она где-то в строке:

set -- {city,town}-*.swf 
[[ ! "$*" =~ \* ]] && mkdir town

или использовать case (как предлагалось в комментариях выше)

case $(ls) in
  *city-*.swf*town-*.swf*) mkdir town ;;
esac
2
27.01.2020, 20:22

Если вы хотите создать резервную копию только каталога , укажите , это должно работать:

Поместите этот сценарий в каталог, который хотите создать резервную копию:

#!/bin/bash

#Check if "backups" exists / if not create folder
if [ ! -d "backups" ]
then
mkdir backups
fi

#Begin Backup
#Choose if you want to use gzip or just tar

#TAR with gzip
#tar -cvfz  --exclude=backups --exclude=${BASH_SOURCE[0]} backups/backup.tar.gz .

#TAR without gzip
#tar -cvf  --exclude=backups --exclude=${BASH_SOURCE[0]} backups/backup.tar.gz .

#NOTE: We exclude "${BASH_SOURCE[0]}" because that's the name of our script,
#      so you can rename it to whatever you like
exit 0
-121--244787-

застежка -молния -r book my/

-r означает рекурсивный.

man zip (или застежка -молния -h в случае, если в вашей системе отсутствуют страницы man) может помочь вам понять и другие полезные варианты.

-121--175389-

Вот решение, которое имеет меньшее влияние, чем выполнение внешней команды ls , а также является более портативным, чем решение, основанное на stat (которое отличается от ОС к ОС).

#!/bin/bash

found=false
for _ in town-*.swf, city-*.swf do
  found=true; break
done

if $found; then
  echo "Yup!"
fi

Подчеркивание является переменной throwway. Цикл для - это простой способ расширить список файлов, и разрыв гарантирует, что циклы, повторяющиеся в длинном списке файлов, не будут потеряны. Исполняемые файлы true и false можно найти в /bin/ или /usr/bin/, и их можно заменить на bash builtins или функции , если вы предпочитаете эту оптимизацию.

Обратите внимание, что это также должно работать в /bin/sh . (По крайней мере, это произошло для меня в паре других операционных систем.)

0
27.01.2020, 20:22

POSIX Определяет опцию -P для утилиты Pathchk ...

  • -P Вместо выполнения проверок на основе Основная файловая система, напишите диагностику для каждого операнда PathName, что:

    • длиннее {_POSIX_PATH_MAX} байтов (см. Минимальные значения в базовых определениях объема IEEE STD 1003.1-2001, глава 13, заголовки)

    • Любой компонент дольше, чем {_POSIX_NAME_MAX} BAYTES

    • содержит любой символ в любом компоненте, который не находится в портативном наборе символов файла

, если имена файлов, которые вы ищете должны соответствовать только символам символов - который состоит из букв ASCII и цифр и ._- / - тогда следующая команда будет работать, а также любая без необходимости делать больше Stat () звонки, чем Оболочка делает их для них:

if    pathchk -p town-*.swf city-*.swf
then  mkdir towns
fi

Еще один способ состоит в том, чтобы глобал путь дважды - один раз для уже известного значения и после неизвестный. Это известное значение шаблона не раздевается, то это потому, что неизвестное значение не разрешило.

Рассмотрим следующее:

mkdir test
touch test/testfile1
echo tes[t]/test*1 tes[t]/test*2

Вывод

test/testfile1 tes[t]/test*2

Здесь мы знаем Путь Путь , и поэтому мы можем проверить его разрешение при попытке сопоставить разрешение неизвестного пути.

Например, предположим, что ваш текущий рабочий каталог состоит полностью из путей, которые не заканчиваются с помощью ? , и нет ни одного из путей, которые либо делают. Это не такое большое предположение, чтобы сделать либо - это может даже быть уверенно, как:

cd /tmp/no_question_mark\? && {
    $_handle_it || exit
};  ln -s "$PWD" /tmp/no_question_marks
    cd /tmp/no_question_marks

, что сделано предположение, вы можете сделать что-то вроде:

set "${PWD%?}"?/town-*.swf "${PWD%?}"?/city-*.swf
case "$*" in (*\?/*) ! echo 'missed at least one...';;
(*) echo 'got em all!'; mkdir towns;;
esac
1
27.01.2020, 20:22

Теги

Похожие вопросы