Intereting Posts
Насколько отличается обработка ввода-вывода на жестком диске в AIX и Redhat Linux? Как сделать запись рабочего стола pcmanfm правой кнопкой мыши только для папки «Рабочий стол»? Как повысить лимит открытых файлов – /etc/security/limits.d vs /etc/security/limits.conf Как я могу добавить пакет сертификатов x509 (ca-bundle.crt) в базу данных NSS (~. / Pki / nssdb) Объединить 2 файла на основе всех доступных значений первого столбца в обоих файлах испорченная нижняя панель – Fedora 14 KDE Нет звука на Ubuntu 11.04 Обертка для менеджеров пакетов Замените строку содержимым файла с помощью sed Можно ли запустить команду из bash и отправить ей нажатие клавиши Что означает ACPI NMI LINT? и почему он меняет версию ядра? Pipe Viewer – следствие производительности монитора Как разбить большой файл на несколько меньших на основе значения в текстовом столбце? Fedora 25 Клавиатура не работает + Ошибка KDE Plasma Как настроить внешние IP-адреса для гостей LXC?

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

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

Первый скрипт в значительной степени является альтернативой команде 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 $