Возможным решением является использование grep с perl-regex. Флаг для этого -P
Например, это должно выглядеть так:
#!/bin/bash
regex="[^-_0-9A-Za-z\. ]+"
while IFS= read -r -d $'\0'; do
filepath=${REPLY%/*}
filename=${REPLY##*/}
#use grep with perl-regex -P and
#-q for quiet to prevent output to stdin
echo "$filename" | grep -qP "$regex"
#now we compare the return code from grep
if [[ "$?" -eq 0 ]]
then
echo "match: $filename"
else
echo "nomatch: $filename"
fi
done < <(find /symlnks -type f -print0)
exit 1
выходит из текущей среды подоболочки с кодом выхода 1, поэтому, например, в:
sh -c '(echo 1; exit 1; echo 2); echo 3'
Это exit 1
выходит из подоболочки, выполняющей код на стороне (...)
, так что 2
не выводится, а родительский процесс оболочки возобновляет эхо 3
.
kill -s PIPE "$$"
¹ отправляет сигнал SIGPIPE процессу, который выполнил интерпретатор оболочки, интерпретирующий в данный момент сценарий. Сигнал SIGPIPE по умолчанию вызывает завершение процессов, и тот факт, что этот процесс был уничтожен SIGPIPE, отражается в его статусе завершения.
Так в:
sh -c '(echo 1; kill -s PIPE "$$"; echo 2); echo 3'
Сигнал SIGPIPE отправляется процессом подоболочки своему родительскому процессу (, который выполнилsh
). Этот родительский процесс умрет и не выведет 3
, в то время как процесс подоболочки продолжит работу в фоновом режиме и выведет 2
.
Если вы запустили эту команду в оболочке bash
или zsh
(и некоторых других оболочках Bourne -, подобных оболочкам ), эти оболочки установят параметр $?
(в их внутреннем представлении. статуса выхода последней команды )на что-то вроде 141, что на большинстве систем равно 128 + SIGPIPE (13 ).
Теперь SIGPIPE — это сигнал, отправляемый системой процессам, пытающимся выполнить запись в канал или сокет, который не имеет конца для чтения (сломанный канал/сокет ), поэтому отправка его здесь немного вводит в заблуждение. Сигналом, зарезервированным для административного завершения процесса, является SIGTERM, который является сигналом kill
, отправляемым по умолчанию.
Одна из причин, по которой вы можете захотеть использовать SIGPIPE вместо SIGTERM, заключается в том, что существуют оболочки, такие как bash
, которые выводят сообщение, когда одно из их заданий завершается сигналом, в то время как они обычно не делают этого для SIGPIPE (, так как процессы обычно завершаются SIGPIPE и не обязательно означают наличие проблемы, как в cmd | head -n 1
), поэтому использование SIGPIPE позволяет избежать таких сообщений.
bash-4.4$ /bin/kill 0
Terminated
bash-4.4$ /bin/kill -s PIPE 0
bash-4.4$
даже если не -интерактивный:
$ bash -c 'sh -c "kill \$\$"; exit'
bash: line 1: 6665 Terminated sh -c "kill \$\$"
$ bash -c 'sh -c "kill -s PIPE \$\$"; exit'
$
1 Здесь добавление отсутствующих кавычек вокруг$$
для надежности и использование стандартного (не -необязательного синтаксиса POSIX)kill -s PIPE
для переносимости (, хотя kill -PIPE
также должен работать на большинстве систем ).