Intereting Posts
Установка Docker на Ubuntu 15.04, невозможность обновления Как установить постоянный путь в @INC Не удалось загрузить драйвер USB-клавиатуры на машине Debian Почему порядок результатов подстановки может отличаться при использовании с терминалом или с perl? У ntpd есть файл drift по умолчанию? текстовый файл с удаленным запросом, связанный с экземпляром vi Защита паролем файла LibreOffice или OpenOffice ODT от Bash Принудительный диск на / dev / sdX Печать всех строк между найденным шаблоном текстового файла в другой файл Установленный Fedora 18 на машине UEFI, получил lvm.mod не найдена ошибка Измените команды на исходные значения Как обновить приглашение на изменение каталога генерировать пароль, который является случайной длиной между 8 – 16 (у меня есть генератор, но его не динамический) Редактирование командной строки bash (быстрые клавиши Emacs) Недавнее изменение приводит к тому, что Shift + Space ничего не делает

Функция со многими аргументами, но только один переключатель

Я делаю сборку мусора через некоторые сценарии, которые я сделал.

Первый скрипт в значительной степени является альтернативой команде rm (вместо того, чтобы фактически удалять файл, он перемещает его в удаленную папку).

Мне удалось разрешить сценарию перемещать несколько файлов в удаленную папку:

sh moveToBin file1 file2 fil3 (similar to: rm file1 file2 file3) 

Начало моего первого скрипта:

 #!/bin/bash for param in "$@" do .. .. (main part of my code) 

Один за другим каждый параметр (файл) перемещается в удаленную папку. Теперь я пытаюсь включить добавление параметров switch -parameters, но я не совсем уверен, как это включить.

Вышеупомянутое работает для sh moveToBin file1 file2 file3 но как я могу включить возможность того, что первый аргумент (только первый) COULD будет переключателем -i (попросить удалить), -v (подтвердить удаление), -iv (попросить удалить затем подтвердите удаление).

Следовательно, коммутатор применяется только к $1 . Я пробовал что-то, называемое getopts, но я не знаком с этим. Когда используется коммутатор, это относится к $2 т.е.

 sh moveToBin -i file1 file2 

это просит удалить файл1, и после того, как я решил, он затем попросит удалить файл2, я подумал о чем-то подобном, но я сомневаюсь, что он сработает. любая помощь?

 counter=1 for param in "$@" do while [[ if $param = "-*" && counter -eq1]]; do getopts "iv" arg; case "$arg" in i) read -p "want to delete $param ?" ans if [ ans =~ ^[Y][y] ] then #run main code for that param value fi;; v) #run main code for that param value echo "file @param deleted";; esac counter=$((counter+1)) continue done #run main code for that param value done 

Условие while while означает, что это первый параметр и этот параметр начинается с дефиса.

Параметры getopts встроены. Вы запускаете его только один раз для всех параметров, затем обрабатываете оставшиеся операнды (необязательные аргументы). getopts позволяет производителю равнодушно писать, например moveToBin -iv file1 или moveToBin -i -v file1 , и вы можете написать moveToBin -- -file для обработки имен файлов, которые начинаются с тире (что-то после -- интерпретируется как операнд).

getopts отслеживает, сколько аргументов уже обработано через переменную OPTIND . Когда он закончит свою работу, OPTIND – это индекс первого операнда; поскольку аргументы нумеруются от 1, это означает, что первые аргументы OPTIND-1 были параметрами.

Пока вы разбираете параметры, вы еще не знаете список файлов для обработки. Поэтому запомните опцию, установив переменную и запросите переменную позже.

 #!/bin/bash confirm= verbose= while getopts 'iv' OPTLET; do case $OPTLET in i) confirm=y;; v) verbose=y;; \?) exit 3;; # Invalid option; getopts already printed an error message esac done shift $((OPTIND-1)) for file in "$@"; do if [[ -n $confirm ]]; then read -p "want to delete $param ?" ans if [[ $ans != [Yy]* ]]; then continue # the user said no, so skip this file fi fi … # do that moving stuff if [[ -n $verbose ]]; then echo "File $file deleted" fi done 

Обратите внимание, что getopts следует традиционной модели синтаксического анализа параметров, где ничего после первого операнда не является опцией. Другими словами, в moveToBin -i foo -v bar есть опция -i а затем три файла foo , -v и bar . Если вы хотите разрешить модель синтаксического анализа GNU, где параметры могут быть смешаны с операндами, getopts не особенно помогает. Также не могут быть использованы getopts bash для анализа длинных опций GNU ( --verbose будет анализироваться как -v -e -r -b -o -s -e плюс ошибка о том, что он не поддерживается).

 #!/usr/bin/env bash VERBOSE=n while getopts "vC:" opt; do case $opt in v) VERBOSE=y ;; C) echo got $OPTARG ;; esac done shift $(($OPTIND - 1)) echo "soooo verbose is $VERBOSE" for x in "$@"; do echo "still got: $x" done 

А потом после обычного чмоддери и еще чего-то:

 $ ./gopt hi there soooo verbose is n still got: hi still got: there $ ./gopt -v hi there soooo verbose is y still got: hi still got: there $ ./gopt -C cats -v hi there got cats soooo verbose is y still got: hi still got: there $