Bash :дочерний процесс и конвейеризация

Чтобы дать интерактивное меню в bash, из которого пользователь может выбрать один из нескольких путей к файлам, вы можете использовать что-то вроде этого:

#!/bin/bash

files=( "$HOME/Desktop/ScreenShot-"*.png )

PS3='Select file to upload, or 0 to exit: '
select file in "${files[@]}"; do
    if [[ $REPLY == "0" ]]; then
        echo 'Bye!' >&2
        exit
    elif [[ -z $file ]]; then
        echo 'Invalid choice, try again' >&2
    else
        break
    fi
done

# use scp to upload "$file" here

Здесь мы используем оператор bashselectдля предоставления меню и третье приглашение PS3для предоставления пользовательского приглашения.

Пользователь может выйти из сценария, не выбирая файл из списка, введя 0в командной строке. Если дан неверный ответ, пользователю предоставляется еще один шанс выбрать файл. Меню -отображается при нажатии . Введите при появлении подсказки.

То, как формулируется логика внутри цикла select, менее важно, поскольку сценарий завершается, когда$REPLY(фактическое значение, введенное пользователем ), равно 0и повторяет попытку, когда$file(значение выбранный из массива )пуст. Альтернативное тело оператора selectможет выглядеть как

if [[ $REPLY == "0" ]]; then
    echo 'Bye!' >&2
    exit
elif [[ -n $file ]]; then
    break
fi

echo 'Invalid choice, try again' >&2

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

files=( "$@" )

В оболочке POSIX у вас обычно нет доступа к именованным массивам или select. Вместо этого вы можете сделать что-то вроде

#!/bin/sh

set -- "$HOME/Desktop/ScreenShot-"*.png

while true; do
    i=0
    for pathname do
        i=$(( i + 1 ))
        printf '%d) %s\n' "$i" "$pathname" >&2
    done

    printf 'Select file to upload, or 0 to exit: ' >&2
    read -r reply

    number=$(printf '%s\n' "$reply" | tr -dc '[:digit:]')

    if [ "$number" = "0" ]; then
        echo 'Bye!' >&2
        exit
    elif [ "$number" -gt "$#" ]; then
        echo 'Invalid choice, try again' >&2
    else
        break
    fi
done

shift "$(( number - 1 ))"
file=$1

# use scp to upload "$file" here

Это довольно распространенный цикл ввода, который повторяется до тех пор, пока пользователь не введет правильную запись (или пока не будет введено 0и скрипт не завершит работу ). Меню re -отображается при каждом неправильном вводе.

Пути вносятся в список позиционных параметров с помощью глобуса оболочки, как и в варианте bash, но меню печатается вручную с целочисленным приращением для каждого выводимого пункта меню.

shiftв конце смещает записи в начале списка позиционных параметров, так что $1становится именем пути, которое пользователь хочет загрузить.

Чтобы вместо этого использовать пути, заданные в командной строке, просто удалите исходную команду set.

1
24.03.2019, 17:23
0 ответов

Теги

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