выйдите из сценария, если ls строка не нашла соответствия

Необходимо подать проценты к индикатору через стандартный вход. Попробуйте это, чтобы видеть, как это работает:

for i in $(seq 1 100); do echo $i; sleep 0.1; done | \
  dialog --gauge "Example" 10 50

Так, в Вашем случае просто сделайте свою работу в подоболочке, произведя число процента время от времени, и передайте его по каналу к dialog. Что-то вроде этого:

(echo 1
 sleep 1
 echo 30
 sleep 1
 echo 90
 sleep 1
 echo 100
) | dialog --gauge "Working hard..." 10 40

(где каждый sleep 1 представляет некоторую реальную работу, конечно...).

Править: Изменение текста

Для изменения текста Вы производите XXX, число, затем новый текст, затем XXX снова. Пример:

(echo 30
 sleep 1
 echo XXX; echo 60; echo "New text"; echo XXX
 sleep 1
 echo 100
) | dialog --gauge "Working hard..." 10 40

Необходимо читать dialogстраница руководства; все объяснено там.

3
14.08.2014, 05:34
2 ответа
{   ls -lrt /dir1/dir2/filename*.txt || 
    kill $$ 
} | tail -1 | 
awk '{print $9}' | 
read variable

Просто убейте сами. Иногда оболочка может быть немного скучной, когда я это делаю, но я нахожу, что она даже не скулит, если я сделаю kill -PIPE $$.

Или если вы хотите уточнить коды возврата и остальное:

trap 'echo some error >&2; exit 1' USR1 $and_or_other_signals
{ ls ... || kill -USR1 $$; } |...

Относительно остального... Может быть по-другому?

touch ~/"a n\$ew file
in 'my home
directory"
v=$(ls -1rdt ~/* || kill -PIPE $$; echo /)
v=${v%?/*}; v=${v##*/}
printf '<%s>' ~/"$v"

OUTPUT

</home/mikeserv/a n$ew file
in 'my home
directory>

Это даст вам имя последнего измененного файла в любом каталоге, независимо от того, какие символы он может содержать. Я использую < >, чтобы обозначить начало и конец переменной и показать, что она не содержит трейлингового пробела. А бит echo должен гарантировать, что если есть трейлинговое белое пространство, то оно сохраняется.

Он определённо бьёт конвейер и всё равно убьёт скриптовый shell, если ls вернётся, кроме 0 - например, когда его аргументы командной строки не существуют.

То же самое можно сделать и без изменения порядка сортировки, но это немного сложнее, и для этого нужно просто перейти в целевую директорию:

touch ~/"a n\$ew file
in 'my home
directory"
v=$(cd ~; ls -dtm ./* || kill -PIPE $$)
v=${v#*/}; v=${v%%,?./*}
printf '<%s>' ~/"$v"

OUTPUT

</home/mikeserv/a n$ew file
in 'my home
directory>

Другой довольно портативный метод, я думаю:

set /[d]ir1/dir2/filename*.txt
[ -z "${1##/\[*}" ] && exit 1
while [ -n "$2" ] 
do  [ "$1" -nt "$2" ] &&
    set "$@" "$1"
shift; done; v=$1
printf %s\\n "$1" "$v"
0
27.01.2020, 21:31

Как написать эту команду

Эта конкретная задача не требует канала.

В zsh:

a=(/dir1/dir2/filename*.txt(Nom[1]))
if ((! #a)); then
  echo >&2 "No file matches /dir1/dir2/filename*.txt"
  exit 2
fi
variable=$a[1]

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

set -e
a=(/dir1/dir2/filename*.txt(om[1]))
variable=$a[1]

Другие оболочки не имеют встроенной функции для поиска самого последнего файла. Вызов ls является разумным при условии, что имена ваших файлов содержат только печатаемые символы, кроме символов новой строки, но не передают параметр -l , а затем разбирают все, кроме имени, что излишне сложно и хрупкие (в частности, разрывы на пробелах). Также возьмите первое совпадение сортировки -t , это быстрее, чем взятие последнего совпадения сортировки -tr . Прямой подход:

variable=$(ls -td /dir1/dir2/filename*.txt 2>/dev/null | head -n 1)
if [ -z "$variable" ]; then
  echo >&2 "No file matches /dir1/dir2/filename*.txt"
  exit 2
fi

Обработка конвейеров

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

set -e -o pipefail
somecommand | filter
echo "somecommand succeeded"

или

set -o pipefail
if ! somecommand | filter; then
  echo >&2 "somecommand or filter failed"
  exit 2
fi

Zsh не имеет параметра pipefail , но вы можете получить код состояния каждого компонента конвейера в массиве pipestatus .

somecommand | filter
if ((pipestatus[1])); then
  echo >&2 "somecommand failed"
  exit 2
fi

В других оболочках статус конвейера - это статус правой команды. Нет прямого способа получить статус левой команды. См. Получение статуса завершения процесса, переданного другому , для некоторых возможных обходных путей.

Помните, что фильтр должен читать весь вывод somecommand , иначе вам нужно обработать случай, когда somecommand умирает из SIGPIPE ].

Если вы хотите действовать на основе того, производит ли somecommand какой-либо вывод, а не на основе его статуса выхода, вы можете использовать ifne из moreutils Джои Хесса . Обратите внимание, что в большинстве систем эти утилиты не установлены по умолчанию.

1
27.01.2020, 21:31

Теги

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