Параметры или аргументы в bash - PullRequest
2 голосов
/ 19 декабря 2011

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

Обычный способ запуска скрипта на терминале - ./scriptname, но позже я ввел аргумент -d.Так что, если я поставлю ./scriptname, он не будет работать.Если я поставлю ./scriptname -d, это будет.

Теперь я хочу поставить еще один аргумент для пути (куда перемещаются файлы, в данном случае "/home/elg19/documents"), чтобы, когда я не включал путь, онне побежитНо если я поставлю ./scriptname -d path, я хочу заменить $To в существующем скрипте аргументом команды после -d.

#!/bin/bash
From="/home/mark/doc"
To=$2

if [ $1 = -d ]; then
    cd "$From"
    for i in pdf txt doc; do
      find . -type f -name "*.${i}" -exec mv "{}" "$To" \;
    done
fi

Ответы [ 2 ]

3 голосов
/ 19 декабря 2011

Ваше желаемое использование не совсем ясно, но, похоже, оно выглядит следующим образом:

scriptname -d path

Таким образом, вы можете сделать это расширяемым способом или методом грубой силы.Так как вы изменяете каталоги невольно, вам также нужно убедиться, что пути абсолютные, а не относительные.

Грубая сила

#!/bin/bash
From="/home/mark/doc"
if [ $# = 2 ] && [ "$1" = '-d' ] && [ -d $2 ]
then
    case "$2" in
    (/*) cd "$From" &&
         for extn in pdf txt doc
         do find . -type f -name "*.$extn" -exec mv {} "$To" \;
         done;;
    (*)  echo "$0: path name must be absolute ($2 is not)" 1>&2; exit 1;;
    esac
else
    echo "Usage: $0 -d /absolute/dirname" 1>&2; exit 1
fi

Расширяемый

#!/bin/bash
From="/home/mark/doc"
To=""

usage()
{
    echo "Usage: $(basename $0 .sh) -d /absolute/dirname" 1>&2
    exit 1
}

while getopts d: opt
do
    case "$opt" in
    (d)  if [ ! -d "$OPTARG" ]
         then echo "$0: $OPTARG is not a directory" 1>&2; exit 1
         else
             case "$OPTARG" in
             (/*) To="$OPTARG";;
             (*)  echo "$0: path name must be absolute ($2 is not)" 1>&2; exit 1;;
             esac
         fi;;
    (*)  usage;;
    esac
done
shift $(($OPTIND - 1))

if [ $# != 0 ] || [ -z "$To" ]
then usage
fi

cd "$From" &&
for extn in pdf txt doc
do find . -type f -name "*.$extn" -exec mv {} "$To" \;
done

Например, будет очень легко добавить опцию -f from, чтобы иметь дело с изменением источника файлов.

Обратите внимание, что вы также можете использовать:

for extn in pdf txt doc
do find "$From" -type f -name "*.$extn" -exec mv {} "$To" \;
done

Это будетпозволяют вам разрешить относительные имена для каталогов from и to, потому что это не меняет каталог.

1 голос
/ 19 декабря 2011

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

#!/bin/bash

usage() {
    echo "USAGE :"
    echo "./move -d <to-directory>"
}

if [ $# -ne 2 ] ; then
    usage
    exit
fi

case $1 in
    -d ) shift
         To=$1
         ;;
    *  ) usage
         exit
esac

From="/tmp/From/"

cd "$From"
for i in pdf txt doc; do
    find . -type f -name "*.${i}" -exec mv "{}" "$To" \;
done

Кроме того, для отладки вашего скрипта вы можете использовать следующую команду:

bash -x ./move.sh -d /tmp/To/

Вы можете добавить дополнительную проверку ошибок (и информативные эхо-запросы) в следующих случаях:

  • Исходный / целевой каталог не завершен
  • N файлов было скопировано из в
  • Нет файлов в
  • Вы можете взять тип файлов в качестве аргументов, например: -t doc xls pdf
...