оболочка linux добавляет в команду переменные параметры - PullRequest
15 голосов
/ 06 августа 2011

Я пытаюсь получить bash-скрипт, который генерирует JSDoc для заданных параметров, например

./jsdoc.sh file.js another.js maybe-a-third.js

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

(также не знаю, как проверить, существует ли param, только если нет exitst if [ -z ... ])

Этот код работает для двух параметров, но, очевидно, это не правильный путь ...

#!/bin/bash

# would like to know how to do positive check
if [ -z "$1" ]
then echo no param
else
        d=$PWD
        cd ~/projects/jsdoc-toolkit/

        # this bit is obviously not the right approach
        if [ -z "$2" ]
        then java -jar jsrun.jar app/run.js -a -t=templates/jsdoc/ $d/$1
        else java -jar jsrun.jar app/run.js -a -t=templates/jsdoc/ $d/$1 $d/$2
        fi

        cp -R out/jsdoc $d
fi

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

Редактировать: Обновлен скрипт в соответствии с ответом @ skjaidev - счастливых дней;)

#!/bin/bash

d=$PWD

for i in $*; do
    params=" $params $d/$i"
done

if [ -n "$1" ]; then
        cd ~/projects/jsdoc-toolkit/
        java -jar jsrun.jar app/run.js -a -t=templates/jsdoc/ $params
        cp -R out/jsdoc $d
fi

Ответы [ 4 ]

15 голосов
/ 06 августа 2011

Для обработки аргументов, содержащих пробелы, используйте "$@" для итерации и сохраните для последующего использования в массиве.

#!/bin/bash
if (( $# == 0 )); then
  echo "usage: $0 file ..."
  exit
fi
dir=$(pwd)
declare -a params
for file in "$@"; do params+=( "$dir/$file" ); done
cd ~/projects/jsdoc-toolkit/
java -jar jsrun.jar app/run.js -a -t=templates/jsdoc/ "${params[@]}"
cp -R out/jsdoc "$dir"
12 голосов
/ 06 августа 2011

$ * имеет все параметры.Вы можете перебирать их

for i in $*;
do
    params=" $params $d/$i"
done
your_cmd $params
3 голосов
/ 06 августа 2011

-n является обратным -z, а "$@" - каноническим способом передачи всех параметров в подкоманду.Это и многое другое можно найти через man bash.

0 голосов
/ 02 августа 2017

Bash-специфических функций (в данном случае массивов) можно избежать, осторожно используя переменную IFS и специальный параметр $@.

#!/bin/sh

dir=$(pwd)

NEW_ARGV=""
# carefully modify original arguments individually and separate them with newlines
# in a new variable (in case they contain spaces)
NEW_ARGV=""
for var in "${@}"
do
    NEW_ARGV="${NEW_ARGV}
${dir}/${var}"
done

SV_IFS=${IFS}
# temporarily set IFS to a newline as per NEW_ARGV setup
IFS="
"
# reset $@ with the modified newline-separated arguments
set -- ${NEW_ARGV}
IFS=${SV_IFS}

# for testing, demonstrate each param is preserved
c=0
for i in "${@}"
do
    c=`expr ${c} + 1`
    echo "args-via-var #${c}: \"${i}\""
done

cd ~/projects/jsdoc-toolkit/
java -jar jsrun.jar app/run.js -a -t=templates/jsdoc/ "${@}"
cp -R out/jsdoc "${dir}"

Сбрасывать $@ необязательно, но это позволяет избежать путаницы с IFS в нескольких местах.Не пропуская $@, нужно устанавливать IFS везде, где разворачивается $NEW_ARGV.

Те, кто уделяет внимание деталям, заметят, что этот метод не сохраняет параметры, если они содержат символы новой строки.Можно было бы использовать любой управляющий символ вместо новой строки, кроме, конечно, NUL, и, возможно, ASCII FS ( разделитель файлов , он же ctrl-\) был бы значимым и очень маловероятным, чтобы происходить вправильное имя файла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...