Bash脚本:更长参数的内部函数别名

时间:2014-04-20 08:32:54

标签: bash alias

假设我已经定义了一个数组,如下所示:

DIR=(A B Supercalifragilistic)

我需要以

的形式调用脚本

./script A B Supercalifragilistic

其中参数由内部函数func1()func2()处理。有没有办法为S创建一个别名(或其他任何东西,但它被称为Supercalifragilistic,以便在我调用时:

./script A B S

内部函数会将S处理/解释为Supercalifragilistic

提前谢谢。


[编辑]

我应该补充说,脚本是通过终端调用的,而不是在脚本中调用的,并且参数A B Supercalifragilistic或(希望)S被传递到终端中的脚本。对不起,我很抱歉。


[EDIT2]

脚本在这里:Bash script: if any argument is "N" then function has extra options,在下面的答案中。它的作用在OP中解释,在脚本下面。最后,代替DIR=(A B C D E F) DIR=(A B Clarification D E F) Clarification(它只是一个示例),文件夹./script a b "d e" g是唯一一个与其他路径不同的路径。我希望现在更清楚,如果没有,请告诉我。


[最终编辑,我希望]

我想我可以大声喊叫#Evrika!"。你的话"硬编码"让我意识到我在任何时候添加/删除新文件夹时修改脚本,所以我想要使数组动态化,如在 array=(a b "d e" g)会产生Clarification >> C 而且它应该用一些短路径(#!/bin/bash array=() for i in "$@" do if [[ "$i" == C ]] then array+=("Clarification") else array+=("$i") fi done echo ${array[*]} echo for i in $(seq 0 $(( $# - 1 ))) do echo ${array["$i"]} done )替换长路径,所以我根据这里的答案制作了这个测试脚本:

$ ./x.sh abc C "d f" e
abc Clarification d f e

abc
Clarification
d f
e

这是它在命令提示符下显示的内容:

{{1}}

我想现在我终于可以让脚本做我想做的事了。谢谢大家的答案。

4 个答案:

答案 0 :(得分:2)

无需使用别名。你可以尝试类似的东西:

$ cat test.sh
#!/bin/bash

declare -a args
for arg in "$@"; do
    [[ $arg = "S" ]] && arg="Supercalifragilistic"
    args+=( "$arg" )
done

for arg in "${args[@]}"; do
    echo "$arg"
done
$ ./test.sh a b S e
a
b
Supercalifragilistic
e

答案 1 :(得分:2)

我真的不知道你到底想要实现什么!但我查看了您在上次编辑中链接的脚本。由于你有一个硬编码的数组,你也可以使用一个关联数组:

declare -A dir_h
dir_h["A"]=A
dir_h["B"]=B
dir_h["C"]=../path/Clarification
dir_h["D"]=D
dir_h["E"]=E

循环dir_h的键,即A B C D E

for k in "${!dir_h[@]}"; do
    echo "$k => ${dir_h[$k]}"
done

尝试一下,这可能会帮助您使用"别名"问题(或不)。


这是您在其他帖子中的脚本,使用此技术并以更一致和可读的形式(注意:我还没有尝试过,可能会有一些小错字,让我知道是否& #39;是这样的):

#!/bin/bash
# ./test.sh     = 1. searches for existing archives
#               1.a. if they exist, it backups them into BKP/.
#               1.b. if not, displays a message
#             2. archives all the directories in the array list
# ./test.sh N       = 1. deletes all the folder's archives existent and
#           specified in the array list
#             2. archives all the directories in the array list
# ./test.sh {A..F}  = 1. searches for existing archives from arguments
#               1.a. if they exist, it backups them into BKP/.
#               1.b. if not, displays a message
#             2. archives all the directories passed as arguments
# ./test.sh {A..F} N    = 1. deletes all the archives matching $argument.zip
#             2. archives all the directories passed as arguments

# The directories to be backed-up/archived, all in the current (script's) path
# except "C", on a different path

declare -A dir_h
dir_h["A"]=A
dir_h["B"]=B
dir_h["C"]=../path/Clarification
dir_h["D"]=D
dir_h["E"]=E
dir_h["F"]=F

declare -A nope_h
nope_h["A"]=bogus
nope_h["B"]=bogus
nope_h["C"]=nope
nope_h["D"]=bogus
nope_h["E"]=bogus
nope_h["F"]=bogus

die() {
   (($#)) && printf >&2 "%s\n" "$@"
   exit 1
}

bak() {

   if [[ "$1" != N ]]; then
      # Check that arg is in dir list:
      [[ -n ${dir_h["$1"]} ]] || die "Error in bak: argument \`$1' not handled"
      if [[ -f $1.zip ]]; then
         mv -vi "$1.zip" "BKP/$1.zip_$(date +"%H-%M")" || die
      else
         echo "$(tput setaf 1) no $1.zip$(tput sgr0)"
      fi
   fi
}

# The archive function, if any argument is "N", processing it is omitted. Folder
# "C" has special treatment
archive() {
   if [[ $1 != N ]]; then
      7z a -mx=9 "$1.zip" "${dir_h["$1"]}" -r -x\!"$1/${nope_h["$1"]}" || die
   fi
}

# Let's check once for all whether N is in the arg list
foundN=0
for a in "$@"; do [[ $a = N ]] && foundN=1 && break; done

if (($#==0)); then
   # case #1: no arguments
   for d in "${!dir_h[@]}"; do
      echo "$(tput setaf 2) backup$(tput sgr0)"
      bak "$d"
      archive "$d"
   done
elif (($#==1)) && ((foundN)); then
   # case #2: one argument, "N"
   for d in "${!dir_h[@]}"; do
      echo "$(tput setaf 1) no backup needed, removing$(tput sgr0)"
      rm -v "$d".zip || die
      archive "$d"
   done
elif (($#>1)) && ((foundN)); then
   # case #3: folders as arguments with "N"
   for f in "$@"; do
      if [[ $f != N ]]; then
         echo "$(tput setaf 1) no backup needed, removing$(tput sgr0)"
         rm -v "$f.zip" || die
      fi
      archive "$f"
   done
else
   for f in "$@"; do
      echo "$(tput setaf 2) backup$(tput sgr0)"
      bak "$f"
      archive "$f"
   done
fi

从这里你可以做很多事情,并且有很多无限的别名"处理可能性。

答案 2 :(得分:1)

你不需要别名。只需将变量S设置为您的字符串:

S=Supercalifragilistic

然后使用:

./script A B "$S"

或者使用array直接调用脚本:

./script ${DIR[@]}

PS: 在shell中使用所有大写变量名称并不是一个好习惯,有时你可能会意外覆盖PATH变量。

答案 3 :(得分:1)

你可以这样做:

processed_directories=()
for dir in "${directories[@]}"
do
    if [ "$dir" = 'S' ]
    then
        dir='Supercalifragilistic'
    fi
    processed_directories+=("$dir")
done

它会在数组中的任何位置用“Supercalifragilistic”替换值“S”。