Linux shell добавляет переменные параметры для команды

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

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

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

(также, не знаю, как проверить, существует ли параметр, только если не 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

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

Изменить: Обновлено script в соответствии с @skjaidev answer - happy days;)

#!/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

Ответ 1

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

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

Ответ 2

Чтобы обрабатывать аргументы, содержащие пробелы, используйте "[email protected]" для итерации и сохранения для последующего использования в массиве.

#!/bin/bash
if (( $# == 0 )); then
  echo "usage: $0 file ..."
  exit
fi
dir=$(pwd)
declare -a params
for file in "[email protected]"; 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"

Ответ 3

-n - это инверсия -z, а "[email protected]" - канонический способ передачи всех параметров в подкоманду. Это и многое другое можно найти через man bash.

Ответ 4

Bash -специфические функции (массивы в этом случае) можно избежать путем тщательного использования переменной IFS и специального параметра [email protected].

#!/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 [email protected] 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}"

Не нужно reset [email protected], но это позволяет избежать возиться с IFS в нескольких местах. Не проходя через [email protected], нужно установить IFS везде, где один расширяется $NEW_ARGV.

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