Обработка строковых операций (и проверка результата grep) в сценарии оболочки

Похоже, вы ищете какой-то вариант именованных каналов (fifos ), созданный с помощью mkfifo.

Тогда вы можете сделать что-то вроде этого:

mkfifo my-pipe
node script.js < my-pipe &

Обратите внимание, что это будет блокироваться до тех пор, пока что-то не откроет мой канал -для записи. Итак, если вы хотите, чтобы script.js мог открывать файл (, но, конечно, еще ничего не читал из него ), то вам нужно открыть его для записи; тривиальный способ — просто перенаправить на него сон(sleep 3650d > my-pipe &). Это также предотвратит получение script.js EOF (конца файла )до тех пор, пока вы не остановите сон (, когда ничего не будет открыто для записи в fifo и все данные исчезнут, сторона чтения получит EOF ).

Теперь вы можете давать ему больше строк в любое время, написав в мой канал -. Любая запись без поиска (или mmap и т. д. )будет работать. Вы можете проверить с помощью echo 'DATA' > my-pipe.

Итак, вместе взятые:

mkfifo my-pipe
node script.js < my-pipe &
sleep 3650d > my-pipe &
sleep_pid=$!
get-data-command > my-pipe     # placeholder for real command to get data
get-data-command > my-pipe
# and so on, for more data.
kill $sleep_pid                # kill the sleep, giving script.js an EOF.

Как указывает Wildcard, на самом деле вы можете захотеть, чтобы script.js открывал прослушивающий сокет и таким образом принимал данные.Вы можете использовать сокеты домена Unix, если хотите избежать необходимости иметь дело с аутентификацией, как это было бы в сокете TCP (, потому что сокеты Unix вместо этого используют права доступа к файлам ).

1
29.06.2019, 18:43
2 ответа

Когда пишешь

 if [ "some string or other" ]
 then

оператор [не выполняет some string or other, он просто видит не -пустую строку и говорит, что это trueзначение.

Вы хотите

 if [ "`synclient | grep TouchpadOff | grep -o -E '[0-9]+'`" ] 

или более современный

if [ "$(synclient | grep TouchpadOff | grep -o -E '[0-9]+')" ]

но на самом деле нет необходимости видеть, создает ли команда строку, так как grep создает код выхода, поэтому

if synclient | grep TouchpadOff | grep -q -E '[0-9]+'
then

должен делать то, что вы хотите. Я не знаю формат вывода synclient, но я ожидаю, что вы сможете объединить два greps в один без особых усилий.

6
27.01.2020, 23:11

икар дал довольно хороший ответ . На ваш вопрос сложно ответить потому что вы не объясняете, что именно должен делать скрипт, поэтому мы вынуждены реконструировать -его (и догадываться, о чем вы думаете ).

Икар догадался, что ты ищешь увидеть содержит ли вывод из synclientстроку который содержит «TouchpadOff» и число.

Я предполагаю, что вы предполагаете / ожидаете что вывод из synclientвключает строку который содержит «TouchpadOff» и число, и вы ищете, равно ли это число 0.

Если Икар угадал правильно, прекратите чтение.

Если я правильно угадал, мы можем адаптировать предпоследнюю (вторую -к -последней )команде в ответ Икара следующим образом:

if [ "$(synclient | grep TouchpadOff | grep -o -E '[0-9]+')" != 0 ]

(, чтобы проверить, равно ли число нулю ), и это должно быть достаточно переносимым. Но может быть несколько более коротких путей:

  • Если вы используете bash, вы можете выполнить

    if (( "$(synclient | grep TouchpadOff | grep -o -E '[0-9]+')" ))

    с использованием синтаксиса ((expression)). Проблемы с этим включают:

    • Это несовместимо с POSIX -, и поэтому поведение в оболочках, отличных от bash придется рассматривать в каждом случае -за -случаем.
    • Если вывод команды равен нулю, он обрабатывается как 0.

  • Если вы знаете больше о том, как выглядит результат synclientчем ты показываешь, можно написать умнее grep. Например, если вы достаточно уверены, что вывод из synclientбудет содержать строку, содержащую строку это похоже на TouchpadOff = number, гдеnumber— отрицательное целое число, отличное от -без ведущего нуля. (, т. е. это может быть 0,  1, или  42,но не 01,  0.5, или  off), и может быть или не быть пробела (с )до и/или после =, то вы можете сделать

    if ! synclient | grep -q 'TouchpadOff[[:space:]]*=[[:space:]]*0'

    В некоторых версиях grep(, например, GNU grep), вы можете сократить это до

    if ! synclient | grep -q 'TouchpadOff\s*=\s*0'

    Я добавил !, чтобы изменить значение истинности команды. grep -q 'TouchpadOff…=…0'будет (явно )успешным если найдет TouchpadOff = 0— но, если моя догадка верна, вы хотите сделать

    synclient TouchpadOff=0
    
    Команда

    , если текущее значение равно , а ненулю.

3
27.01.2020, 23:11

Теги

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