Создайте сценарий удара, который позволяет Вам выбирать несколько опций вместо всего один?

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

[X] Copy only (1) - Options typed by the user
[ ] Move only (2)
[X] Checksum  (3) - Options typed by the user
[ ] Reset permission (4)
[ ] Exit (5)

Select choice:

Я нашел некоторые опции, но я не знаю, как заставить их сделать определенную функцию, потому что я не понимаю, как код работает.

Обновление:

Функциональный код:

#!/bin/bash

#Contributing code by Sergiy Kolodyazhnyy and adaptation for MarianoM.

resize -s 40 90 > /dev/null #Change window size.

option=$(dialog --clear --backtitle "Synchronization..." --title "Synchronize" \
    --checklist "Select the synchronization options:"  20 50 10 \
       checksum "Compare the content" off \
       detail "Show more information" off \
       directory "Synchronize folders" on \
       recursive "Include subfolders" off 2>&1 > /dev/tty)

for i in $option; do #Set parameter of the menu options.
       case $i in
         checksum) c="-c" ;;
         detail) v="-v" ;;
         directory) d="-d" ;;
         recursive) r="-r" ;;
       esac
     done

if [ -z $option ]; then #Check if the variable is empty. If it is empty, it means that the user has not chosen an option.
 clear 
 echo
 echo "Error: No option has been selected or dialog not installed. The program can not continue."
 echo  
   else
 clear
   source=$(dialog --clear --backtitle "Please select source..." --title "Source:" --fselect "" 20 50 2>&1 > /dev/tty)
     if [ -z $source ]; then
       clear
       echo
       echo "Error program. Source not selected, try again!"
       echo
       exit
     fi
 clear
 destination=$(dialog --clear --backtitle "Please select destination..." --title "Destination:" --fselect "" 20 50 2>&1 > /dev/tty)
     if [ -z $destination ]; then
       clear
       echo
       echo "Error program. Destination not selected, try again!"
       echo
       exit
     fi
 clear
 rsync  "$c" "$v" "$d" "$r" "$source" "$destination"
 echo
fi
exit
1
задан 7 January 2019 в 20:19

1 ответ

Из обсуждения в комментариях очевидно, что Ваше основное беспокойство состоит в том, чтобы создать как сценарий со множественными выборами, а не сфокусироваться на копировании/перемещении самих файлов, и операции файла являются просто примером. Эта функциональность может быть достигнута через dialog команда, которая позволяет создавать текстовые пользовательские интерфейсы, с --checklist отметьте конкретно; однако нет ничего на стандартной панели инструментов только для оболочки для достижения того, что Вы хотите. Следовательно, dialog соответствующий инструмент для этого задания.

Ниже Вас найдет сценарий в качестве примера. В то время как сценарий реализует только 3 опции, которые были обсуждены, он обеспечивает достойную начальную точку, какие пользователи могут степень далее и также обращаются к взаимоисключающим опциям, как упомянуто в комментариях. Особенно, множественный выбор обращен в menu() функция, которая служит оберткой для dialog с --checklist опция

Для хранения вещей простыми все, в чем Вы действительно нуждаетесь, является этим:

output=$(dialog --clear --backtitle "Backtitle. Use <SPACE> to select." --title "My Dialog" \
       --checklist "Select all that apply"  50 50 100 \
       checksum "SHA-256" off \
       copy "Copy only (exclusive with move)" off \
       move "Move only (exclusive with copy)" off 2>&1 > /dev/tty)

Это сохраняет выбор нескольких объектов к переменной $output. Примечание, что '2> &1>/dev/tty) в конце крайне важны для сохранения возвращаемого значения в переменную. Но см. сценарий ниже для более практического примера:

#!/bin/bash

puke(){
    # function to exit with specific error message
    # analogous to 'die' in Perl
    printf ">>> Errors were encountered: %s\n" "$1" && exit
} > /dev/stderr

menu(){
    # dialog --help documents the option as follows:
    # --checklist    <text> <height> <width> <list height> <tag1> <item1> <status1>...
    # tags are what the output returns.
    # We can use word-splitting 
    # and iterate over output of this function in order. Of course first option
    # being checksum will always work and is not mutually exclusive with anything else
    dialog --clear --backtitle "Backtitle. Use <SPACE> to select." --title "My Dialog" \
           --checklist "Select all that apply"  50 50 100 \
           checksum "SHA-256" off \
           copy "Copy only (exclusive with move)" off \
           move "Move only (exclusive with copy)" off || puke

} 2>&1 1>/dev/tty

select_file(){
    dialog --backtitle "Choose file by typing or navigating and selecting with <SPACE>" --fselect "/etc/" \
           20 50  || puke
} 2>&1 1>/dev/tty


iter_actions(){
    # variables are available to child functions
    # Since we call iter_actions in main(), this
    # function also knows about main's variable $fselect

    for i ; do 
       case "$i" in
           checksum) sha256sum "$fselect" ;;
           copy) cp "$fselect" /tmp ;;
           move) mv "$fselect" /tmp ;;
       esac
    done
}

main(){
    # here I'm using /etc but you can use $PWD to default to user's 
    # current working directory, or accept positional parameters from command-line
    # as in $1, $2 and so forth
    fselect=$( select_file "/etc" )
    actions=$(menu) 
    printf "\r%b" "\033c" # this clear the screen

    case "$actions" in
       *copy*move|*move*copy) puke "Mutually exclusive options selected" ;;
        *) iter_actions $actions ;; # note here variable is unquoted on purpose
    esac
}

# script entry point
main "$@"

Для дальнейшего исследования:

3
ответ дан 3 December 2019 в 07:22

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

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