19

我正在尝试获取一个 bash 脚本,该脚本为这样的给定参数生成 JSDoc

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

我陷入了如何将未知数量的参数传递给下一个 shell 命令的问题。

(另外,不知道如何检查参数是否存在,只有在不存在时才 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

4 回答 4

17

$* 具有所有参数。你可以遍历它们

for i in $*;
do
    params=" $params $d/$i"
done
your_cmd $params
于 2011-08-05T21:40:54.547 回答
17

要处理包含空格的参数,请使用"$@"来迭代,并将其存储在数组中以供以后使用。

#!/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"
于 2011-08-05T22:15:59.197 回答
4

-n是 的倒数-z,并且"$@"是将所有参数传递给子命令的规范方式。这和更多可以通过找到man bash

于 2011-08-05T21:41:40.483 回答
1

IFS通过仔细使用变量和特殊$@参数,可以避免 Bash 特定的功能(在这种情况下为数组) 。

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

没有必要 reset $@,但这样做可以避免IFS在多个地方弄乱。不用经过$@一个必须IFS到处设置一个扩展$NEW_ARGV

注重细节的人会注意到,此方法在包含换行符时不会保留参数。可以使用任何控制字符代替换行符,当然,除了NULASCII FS(文件分隔符,又名ctrl-\)可能既有意义又不太可能出现在有效的文件名中。

于 2017-08-01T23:56:34.030 回答