файлы списка tar, разрыв первого файла

SIGTERM — это сигнал, который обычно используется для административного завершения процесса.

Это не сигнал, который посылает ядро, но это сигнал, который обычно посылает процесс, чтобы завершить (мягко) другой процесс.

Это сигнал, который по умолчанию отправляется командами kill, pkill, killall...

Это сигнал, который посылается демонам для их остановки (например, при остановке какой-либо службы) или посылается initперед выключением (за которым следует SIGKILL для этих процессов которые не успели вовремя расторгнуть по SIGTERM).

Обратите внимание, что SIGTERM — это , а не сигнал, который отправляется после ^C. Сигнал, отправленный после ^C, является SIGINT.

1
13.04.2017, 15:37
3 ответа

Вы можете указать AWK выйти после печати чего-либо:

awk -F/ '$NF != "" { print $NF; exit }'

Поскольку вы ищете конкретное имя файла:

awk -F/ '/my-file-name\.ext$/ && $NF != "" { print $NF; exit }'

Тест $ NF является избыточным, тогда:

awk -F/ '/my-file-name\.ext$/ { print $NF; exit }'
2
27.01.2020, 23:16

попробуйте что-нибудь вроде

 tar tzf "archive.tar.gz" | awk -F/ '$NF ~ /my-filename$/ {print $NF ; exit }'

или

 tar tzf "archive.tar.gz" | awk -F/ 'substr($NF,4,11) == "my-filename" {print $NF ; exit }'

(где 4 и 11 должны совпадать с фактическим именем файла).

2
27.01.2020, 23:16

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

  • В foo | бар , бар выходит.
  • Завершение процесса закрывает конец канала для чтения.
  • Когда foo пытается записать в канал, он получает сигнал SIGPIPE.
  • foo умирает.

Предполагается, что foo не защищен от SIGPIPE; программы могут это делать, но типичные программы командной строки - нет.

Поскольку вам нужно только одно совпадение, завершите awk, как только он найдет интересующую вас строку:

tar tzf "archive.tar.gz" | awk -F/ '$NF ~ /.my-file-name\.ext$/ {print $NF; exit}'

или (здесь не очень выгодно)

tar tzf "archive.tar.gz" | sed -n '/[^/]my-file-name\.ext$/ {s!.*/!!; q}'

или, придерживаясь вашего более сложного подхода с использованием grep отдельно от awk

tar tzf "archive.tar.gz" | awk -F/ '{ if($NF != "") print $NF }' | grep -e "^..*my-file-name\\.ext$" | head -n 1

При выходе из программы чтения tar завершает свою работу при следующей записи в конвейер, что может занять некоторое время из-за буферизации вывода . (Это займет особенно много времени, если в конвейере более двух процессов, поскольку для каждого из них будет некоторая задержка на получение SIGPIPE.) После выхода awk , find потратит немного времени на чтение архива и заполнение следующего буфера именами файлов, а затем, наконец, попытается записать буфер и погибнет с помощью SIGPIPE. Для этого приложения, скорее всего, было бы быстрее переключить tar на буферизацию строки для вывода, что вы можете сделать с помощью stdbuf :

stdbuf -oL tar tzf "archive.tar.gz" | awk -F/ '$NF ~ /.my-file-name\.ext$/ {print $NF; exit}'

В качестве альтернативы вы можете убить программу tar при выходе из awk, но это более сложно.

sh -m 'tar tzf "archive.tar.gz" | {
         awk -F/ "$0";
         kill -TERM -$$;
       }' '$NF ~ /.my-file-name\.ext$/ {print $NF; exit}'
[ $? -eq 143 ]
1
27.01.2020, 23:16

Теги

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