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

Необходимо будет сохранить информацию о метаданных:

cd chroot && bsdtar cf - . | nice lzop | ssh user@dest '
  cd chroot && nice lzop -d | bsdtar --numeric-owner -xpSf -'

(сюда использование lzop сжимать поток для сохранения пропускной способности будучи хорошим на ЦП)

Или:

rsync --verbose --archive --one-file-system \
      --xattrs --hard-links --numeric-ids --sparse --acls \
      chroot/ user@dest:chroot/
2
21.08.2015, 00:51
2 ответа

Встроенная функция 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 ] и бар . Если вы хотите разрешить модель синтаксического анализа опций GNU, в которой опции могут быть смешаны с операндами, getopts не особенно полезны.Не может также встроенный bash getopts синтаксический анализ длинных параметров GNU ( - verbose будет анализироваться как -v -e -r -b -o -s -e plus ошибка о неподдерживаемых - ).

3
27.01.2020, 22:05
#!/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

А затем, после обычного chmoddery и еще много чего:

$ ./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
$ 
0
27.01.2020, 22:05

Теги

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