bash
:shopt -s nullglob
files=(/mydir/*.gz)
((${#files[@]} == 0)) || gzip -d -- "${files[@]}"
zsh
: files=(/mydir/*.gz(N))
(($#files == 0)) || gzip -d -- $files
Обратите внимание, что в zsh
, без (N)
, как в оболочках до-Bourne, csh или tcsh, если glob не совпадает, команда не выполняется, вы сделаете это только для того, чтобы избежать сообщения об ошибке (no match found, в отличие от gzip
, не выполняющего расширенный glob в случае bash
или других Bourne-подобных оболочек). Вы можете добиться того же результата с bash
с помощью shopt -s failglob
.
В zsh
ошибка failing glob - это фатальная ошибка, которая приводит к завершению работы оболочки (если она не интерактивная). Вы можете предотвратить выход вашего скрипта в этом случае либо с помощью вложенной оболочки, либо используя zsh
механизм перехвата ошибок ({ try-block; } always { error-catching; }
), (или установив опцию nonomatch
(чтобы работать как sh
), nullglob
или noglob
, хотя я бы не рекомендовал этого делать):
$ zsh -c 'echo zz*; echo not output'
zsh:1: no matches found: zz*
$ zsh -c '(echo zz*); echo output'
zsh:1: no matches found: zz*
output
$ zsh -c '{echo zz*;} always {TRY_BLOCK_ERROR=0;}; echo output'
zsh:1: no matches found: zz*
output
$ zsh -o nonomatch -c 'echo zz*; echo output'
zz*
output
ksh93
в конечном итоге добавил механизм, подобный zsh
's (N)
glob qualifier, чтобы избежать необходимости устанавливать nullglob
опцию глобально:
files=(~(N)/mydir/*.gz)
((${#files[@]} == 0)) || gzip -d -- "${files[@]}"
Переносимо в POSIX sh
, где несовпадающие глобы передаются нерасширенными без возможности отключить это поведение (единственной опцией POSIX, связанной с глобами, является noglob
для полного отключения глобирования), трюк заключается в том, чтобы сделать что-то вроде:
set -- /mydir/[*].gz /mydir/*.gz
case $#$1$2 in
'2/mydir/[*].gz/mydir/*.gz') : no match;;
*) shift; gzip -d -- "$@"
esac
Идея в том, что если /mydir/*. gz
не совпадает, то он расширится до самого себя (/mydir/*.gz
). Однако он также может расшириться до него, если существует файл с именем /mydir/*.gz
, поэтому, чтобы различать эти случаи, мы также используем глобу /mydir/[*].gz
, которая также расширится до /mydir/*.gz
, если существует файл с таким именем.
Поскольку это довольно неудобно, вы можете предпочесть использовать find
в таких случаях:
find /mydir/. ! -name . -prune ! -name '.*' \
-name '*.gz' -type f -exec gzip -d {} +
The ! -имя . -prune
заключается в том, чтобы не заглядывать в подкаталоги (некоторые реализации find
имеют -depth 1
или -mindepth 1 -maxdepth 1
в качестве эквивалента). ! -name '.*'
- это исключение скрытых файлов, как это делают глобы.
Преимуществом является то, что он все еще работает, если список файлов слишком велик, чтобы уложиться в ограничение размера аргументов выполняемой команды (find
выполнит несколько команд gzip
, чтобы избежать этого, ksh93
и zsh
также имеют механизмы для обхода этого).
Еще одно преимущество - вы получите сообщения об ошибках, если find
не сможет прочитать содержимое /mydir
или не сможет определить тип файлов (globs просто молча проигнорирует проблему и будет действовать так, как будто соответствующих файлов не существует).
Небольшим недостатком является потеря точного значения статуса выхода gzip
(если хоть одно обращение gzip
завершится с ненулевым статусом выхода, find
все равно завершится с ненулевым статусом выхода (хотя и не обязательно с тем же), так что для большинства случаев этого достаточно).
Еще одно преимущество - вы можете добавить -тип f
, чтобы избежать попыток распаковки каталогов или fifos/устройств/сокетов..., имя которых заканчивается на .gz
. За исключением zsh
(*.gz(.)
только для обычных файлов), глобы не могут фильтровать по типам файлов, вам нужно сделать что-то вроде:
set --
for f in /mydir/*.gz
[ -f "$f" ] && [ ! -L "$f" ] && set -- "$@" "$f"
done
[ "$#" -eq 0 ] || gzip -d -- "$@"
вы также можете сделать это с помощью следующей команды:
gpasswd -a
вы должны получить что-то вроде : Добавление пользователя в группу wheel
Для просмотра групп пользователей вы можете использовать: groups
Попробуйте перезагрузиться. Похоже, вы определенно находитесь в группе колес. Вероятно, вы просто не полностью выходите из системы; завершение работы устранит любые сомнения в том, что вы вышли из системы.