Заставить процесс игнорировать / отклонять накопленный ввод во время приостановки?

В оболочке Bourne есть конструкция для этого. Это то же самое, что и в современном sh (который больше похож на то, что вы используете, оболочка Bourne не поддерживает $ (...) ; если это была оболочка Bourne , вы получите другую ошибку):

case $1 in
  *"$2"*) printf '"%s" is in "%s"\n' "$2" "$1"
esac

Если вы хотите использовать grep , это будет:

if printf '%s\n' "$1" | grep -Fqe "$2"; then
  printf '"%s" is in "%s"\n' "$2" "$1"
fi

или

if grep -Fqe "$2" << EOF
$1
EOF
then
  printf '"%s" is in "%s"\n' "$2" "$1"
fi

Но это будет работать правильно, только если $ 2 не содержал символа новой строки.

В любом случае, вам нужно заключить в кавычки большую часть этого расширения параметров. Единственное место, где он не нужен, - это случай $ 1 выше, но даже тогда случай «1 доллар» не повредит.

Несколько примечаний к вашему коду:

  1. Вы не можете использовать echo для произвольных строк .Здесь, в зависимости от реализации echo , он не сработает для значений $ 1 , например -n или foo \ bar .
  2. Оставление расширения параметра без кавычек имеет особое значение в оболочках . Вы не хотите этого делать. Попробуйте, например, grep -c $ 2 со значением $ 2 , например * или root / etc / passwd .
  3. grep без -F предназначен для сопоставления регулярных выражений. Вам понадобится -F для поиска по фиксированной строке (подстроке) (раньше было с fgrep ), но опять же, если $ 2 содержит несколько строк, это говорит grep -F для поиска любого содержимого этих строк во входных данных ( grep -F $ 'a \ nb' будет искать a ] или b , а не $ 'a \ nb' строка).
  4. В grep -c $ 2 содержимое $ 2 будет использоваться в качестве опции, если оно начинается с - . Чтобы этого избежать, вы хотите grep -c -e "$ 2" или grep -c - "$ 2" .
  5. Вы хотите использовать статус выхода, а не стандартный вывод для сообщения логических условий. В сценариях с exit ( exit 0 для истины, exit 1 (или любое ненулевое число, но избегайте значений больше 120) для false). Для функций используйте вместо этого return . Хотя и скрипты, и функции вернутся со статусом последней команды запуска.
  6. $ (cmd) расширяет до вывода cmd (и подвергается здесь split + glob из-за отсутствия кавычек снова) за вычетом завершающих символов новой строки. Таким образом, если cmd выводит 0 \ n , $ (cmd) расширяется до 0 . Итак, при запуске $ (cmd) пытается выполнить команду с именем 0 . Если вы хотите преобразовать вывод cmd в статус выхода (чтобы его можно было использовать как логическое), вам понадобится (exit «$ (cmd)») . Это запускает подоболочку, которая завершается с выводом cmd в качестве кода выхода).
  7. grep -c подсчитывает количество вхождений. Здесь вам не обязательно иметь полный счет, вам нужно только знать, найдено ли оно вообще (есть ли хотя бы одно совпадение).Для этого grep -q более эффективен, так как он прекращает поиск после того, как нашел его. Для старых реализаций grep , которые не поддерживают (стандартный) -q параметр, вы можете использовать fgrep -le "$ 2"> / dev / null . С -l , fgrep также останавливается при первом совпадении, но выводит имя файла (которое мы здесь отбрасываем, перенаправляя вывод на / dev / null ) .

2
13.04.2017, 15:36
1 ответ

Вы можете приостановить только awk и промыть канал, который он читает, из-под ног, прежде чем возобновить его. В системах на базе Linux и с GNU dd :

Где $ pid - это PID awk :

kill -s STOP "$pid"

, чтобы остановить его, и

dd iflag=nonblock if="/proc/$pid/fd/0" > /dev/null; kill -s CONT "$pid"

возобновить.

Предполагается, что канал не заполнен (64 КБ по умолчанию в Linux), иначе tail также мог быть заблокирован. Чтобы обойти это, вы можете промыть трубу с помощью:

socat -T0.2 -u "/proc/$pid/fd/0" /dev/null

Это промоет то, что в данный момент находится в трубе, и продолжит чтение до тех пор, пока не перестанет поступать в течение 0,2 секунды, чтобы позволить tail догнать то, что он не имеет » Не читал из файла, если он есть.

2
27.01.2020, 22:10

Теги

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