№
wait
используется исключительно в родительском процессе для ожидания завершения дочернего процесса (и для доступа к его статусу выхода ).
Кроме того, ни один процесс не может перехватывать KILL
сигнал (исходного вопроса, использованного KILL
в качестве примера ).
Кроме того, "ожидание сигнала" - необычная вещь.поскольку сигналы являются асинхронными событиями, то есть вы не ждете их, а вместо этого устанавливаете обработчик сигналов (с помощью trap
в оболочке ), который будет обрабатывать сигнал всякий раз, когда Он прибывает. Сигнал может поступить в любой момент во время выполнения сценария, и обработчик сигнала будет выполнен, когда это произойдет (нормальный ход программы временно приостановится на время обработки сигнала ).
Очевидно, вы могли бы сделать что-то вроде
trap 'quit=1' USR1
quit=0
while [ "$quit" -ne 1 ]; do
printf 'Do "kill -USR1 %d" to exit this loop after the sleep\n' "$$"
sleep 1
done
echo The USR1 signal has now been caught and handled
для выполнения своего рода цикла «ожидание поступления сигнала».
Здесь «ловушка» будет «ловить» сигнал USR1
, «обработчик» установит quit
в 1
, и управление будет возвращено коду, который выйдет из цикла.
Не анализировать вывод ls
(, см., например,. Почему *не *parse `ls`(и что делать вместо )?). Проблема, с которой вы сталкиваетесь, заключается в том, что ваша переменная цикла file
будет принимать значения ваших имен файлов после того, как все они будут объединены в одну длинную строку, а затем разделены на пробелы (и после любого разделения -. ] вверх слово, которое оказалось шаблоном подстановки, было расширено ). Вы получите три итерации цикла для имени файла XXX XXXX XXX-6VwvOkZvzuI.description
, например, по одной для значений XXX
, XXXX
и XXX-6VwvOkZvzuI.description
.
Для перебора всех файлов, в именах которых есть тире, а затем суффикс имени файла .description
, используйте
for name in *-*.description; do...; done
Чтобы выделить часть перед -
в $name
, используйте стандартное расширение параметра, которое удаляет все после первого -
в строке:
prefix=${name%%-*}
Разница между использованием %%
и %
здесь заключается в том, что с %%
удаляется самая длинная совпадающая хвостовая строка. Это имеет значение, если в имени содержится несколько символов -
.
Ваша петля становится
for name in *-*.description; do
prefix=${name%%-*}
done
Суффикс имени файла уже известен (.description
), но вы можете получить часть имени файла от -
до суффикса, используя
infix=${name#"$prefix"}
infix=${infix%.description}
Наконец, с таким скриптом, как
#!/bin/sh
suffix=.description
for name in *-*"$suffix"; do
prefix=${name%%-*}
infix=${name#"$prefix"}
infix=${infix%.description}
printf 'prefix="%s", infix="%s", suffix="%s"\n' \
"$prefix" "$infix" "$suffix"
done
вы получите
$ ls
XXX XXXX XXX-6VwvOkZvzuI.description XXX XXXX XXX-6VwvOkZvzuK.description
XXX XXXX XXX-6VwvOkZvzuJ.description script
$./script
prefix="XXX XXXX XXX", infix="-6VwvOkZvzuI", suffix=".description"
prefix="XXX XXXX XXX", infix="-6VwvOkZvzuJ", suffix=".description"
prefix="XXX XXXX XXX", infix="-6VwvOkZvzuK", suffix=".description"
Я оставлю свой ответ, но добавлю предупреждение из ответа @Kusalananda :Не проанализируйте вывод ls
(, см., например. Почему *не *parse `ls`(и что делать вместо )?).
Вы можете направить вывод ls напрямую в sed и заменить только часть стоит перед дефисом(-
):
ls *.d* | sed 's/\(.*\)-.*/\1/'
Я попробовал это с двумя файлами с именами:
XXX XXXX XXX-6VwvOkZvzuI (copy).description
XXX XXXX XYZ-6VwvOkZvzuI.description
и вывод:
XXX XXXX XXX
XXX XXXX XYZ
Команда sed работает следующим образом:
\(
и \)
, которые в этом case - все до последнего дефиса в имени файла (, которое вам нужно адаптируйте его, если ваши файлы имеют более поздние дефисы в именах)\1
-, то есть только часть XXX При необходимости вы можете поместить вывод команды в файл с помощью:
ls *.d* | sed 's/\(.*\)-.*/\1/' > new_file
Попробуйте это
$ ls -1
x.sh
XXX XXXX XXX-6VwvOkZvzuI.description
YYY XXXX XXX-6VwvOkZvzuI.description
$ cat x.sh
#!/bin/bash
for file in *.d*
do
fname=${file/-*/}
ext=${file/*-/}
echo fname $fname ext $ext
done
$./x.sh
fname XXX XXXX XXX ext 6VwvOkZvzuI.description
fname YYY XXXX XXX ext 6VwvOkZvzuI.description
$