Необходимо подать проценты к индикатору через стандартный вход. Попробуйте это, чтобы видеть, как это работает:
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
страница руководства; все объяснено там.
{ 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"
</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"
</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"
Эта конкретная задача не требует канала.
В 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 Джои Хесса . Обратите внимание, что в большинстве систем эти утилиты не установлены по умолчанию.