Как я могу использовать канал в некоторое время условии?

Я хочу циклично выполниться, в то время как grep делает или не находит что-то, что я могу записать:

while grep 'matches' inLogFile.txt
do
  echo good.
  sleep 10
done

Или

while grep -v 'notHereYet' inLogFile.txt
do
  sleep 2
done
echo -e '\a'Yo! It is here now.

Я ввожу их при интерактивном приглашении оболочки.

Таким образом, я хотел неоднократно проверить df поскольку, когда объем на самом деле был смонтирован, отчасти как:

while df | grep -v '/toBeMounted'
do
  sleep 2
done
echo -e '\a'Hey, I think you wanted to know that /toBeMounted is available finally.

Я испытываю затруднения при выяснении, как сгруппировать канал в условие.

Я знаю, что мог сделать что-то как:

while [ -z "$(df|grep '/toBeMounted')" ]
do
  sleep 2
done
echo -e '\a'Okay that is finally present now.

Все же я чувствую, как будто должен быть способ сделать это с помощью значений выхода вместо сравнения строк.

4
задан 16 September 2016 в 23:42

2 ответа

Для разбираний в логике просто незначительные изменения требуются. Используйте:

while ! df | grep '/toBeMounted'
do
  sleep 2
done
echo -e '\a'Hey, I think you wanted to know that /toBeMounted is available finally.

Обсуждение

Соответствующий код в вопросе был:

while df | grep -v '/toBeMounted'

Код выхода конвейера является кодом выхода последней команды в конвейере. grep -v '/toBeMounted' возвратится верный (code=0), если по крайней мере одна строка входа не будет соответствовать /toBeMounted. Таким образом это тестирует, существуют ли другие вещи, смонтированные, кроме того, /toBeMounted. Это нисколько не, что Вы ищете.

Использовать df и grep протестировать ли /toBeMounted смонтирован, нам нужно

df | grep '/toBeMounted'

Это возвращает true если /toBeMounted смонтирован. То, в чем Вы на самом деле нуждаетесь, является отрицанием этого: Вам нужно условие, которое верно если /toBeMounted не смонтирован. Чтобы сделать это, мы просто должны использовать отрицание, обозначенное !:

! df | grep '/toBeMounted'

И, это - то, что мы используем в коде выше.

Документация

Из руководства Bash:

Статус возврата конвейера является статусом выхода последней команды, если pipefail опция не включена. Если pipefail включен, статус возврата конвейера является значением последней (самой правой) команды, которая выйдет с ненулевым состоянием или нулем, если все команды выходят успешно. Если зарезервированное слово ! предшествует конвейеру, статус выхода того конвейера является логическим отрицанием статуса выхода, как описано выше. Оболочка ожидает всех команд в конвейере для завершения прежде, чем возвратить значение.

10
ответ дан 23 November 2019 в 11:39

То, что Вы используете df с grep говорит мне, что Вы фильтруете вывод df пока некоторое устройство не монтируется к определенному каталогу, т.е. является ли это в списке.

Вместо того, чтобы фильтровать внимание списка на каталог, который Вы хотите. Luckly для нас, утилиты mountpoint позволяет нам делать точно, что, и позволяет иметь дело со статусом выхода той команды. Рассмотрите это:

$ mountpoint  /mnt/HDD/                                                        
/mnt/HDD/ is a mountpoint
$ echo $?
0
$ mountpoint  ~                                                                
/home/xieerqi is not a mountpoint
$ echo $?
1

Ваш сценарий таким образом, может быть переписан как

while ! mountput /toBeMounted > /dev/null
do
   sleep 3
done
echo "Yup, /toBeMounted got mounted!"

Образец выполняется с моим собственным диском:

$ while ! mountpoint /mnt/HDD > /dev/null
> do 
>     echo "Waiting"
>     sleep 1
> done && echo "/mnt/HDD is mounted"
Waiting
Waiting
Waiting
Waiting
Waiting
/mnt/HDD is mounted

На ноте стороны Вы можете довольно легкая реализация Ваша собственная версия mountpoint команда, например, в Python, как я сделал:

#!/usr/bin/env python3
from os import path
import sys

def main():

    if not sys.argv[1]:
       print('Missing a path')
       sys.exit(1)

    full_path = path.realpath(sys.argv[1])
    with open('/proc/self/mounts') as mounts:
       print
       for line in mounts:
           if full_path in line:
              print(full_path,' is mountpoint')
              sys.exit(0)
    print(full_path,' is not a mountpoint')
    sys.exit(1)

if __name__ == '__main__':
    main()

Образец выполняется:

$ python3 ./is_mountpoint.py /mnt/HDD                                          
/mnt/HDD  is mountpoint
$ python3 ./is_mountpoint.py ~                                                 
/home/xieerqi  is not a mountpoint
4
ответ дан 23 November 2019 в 11:39

Другие вопросы по тегам:

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