开发者

linux shell append variable parameters to command

开发者 https://www.devze.com 2023-03-26 01:05 出处:网络
I am trying to get a bash script that g开发者_C百科enerates JSDoc for given parameters like this

I am trying to get a bash script that g开发者_C百科enerates JSDoc for given parameters like this

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

I am getting stuck on how to pass an unknown quantity of parameters to the next shell command.

(also, don't know how to check if param exists, only if not exitst if [ -z ... ])

This code works for up to two parameters, but obviously not the right way to go about it...

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

Any other pointers of how I could achieve this would be appreciated.

Edit: Updated script according to @skjaidev's 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


$* has all the parameters. You could iterate over them

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


To handle arguments that contain whitespace, use "$@" to iterate, and store the for later use in an array.

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


-n is the inverse of -z, and "$@" is the canonical way to pass all parameters on to a subcommand. This and more can be found via man bash.


Bash-specific features (arrays in this case) can be avoided through careful use of the IFS variable and the special $@ parameter.

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

It's not necessary to reset $@, but doing so avoids messing with IFS in multiple places. Without going through $@ one must set IFS everywhere one expands $NEW_ARGV.

Those with an eye for detail will note that this method does not preserve parameters when they contain newlines. It would be possible to use any control character in place of newline, except of course NUL, and perhaps ASCII FS (file separator, aka ctrl-\) would be both meaningful and very unlikely to occur in a valid filename.

0

精彩评论

暂无评论...
验证码 换一张
取 消