bash脚本:内部函数别名不再争论(Bash script: internal function a

2019-10-19 22:37发布

假设我已经定义了一个阵列,这样的:

DIR=(A B Supercalifragilistic)

我需要调用脚本

./script A B Supercalifragilistic

其中参数通过内部功能处理的func1()func2() 有没有一种方法,使一个别名(或任何东西,但是这就是所谓的) SSupercalifragilistic以至于当我调用:

./script A B S

内部功能将处理/解释S作为Supercalifragilistic

先感谢您。


[编辑]

我要补充的是,脚本调用经由终端,而不是一个脚本的内部,并且所述参数AB Supercalifragilistic ,或(希望) S ,是在以所述终端的所述脚本传递。 我的混乱很抱歉。


[EDIT2]

该脚本是在这里: bash脚本:如果任何参数是“N”,那么功能有额外的选项 ,在下面的答案。 它的作用是在OP解释那里,下面的脚本。 最后,代替DIR=(ABCDEF)它的DIR=(AB Clarification DEF)它只是一个例子)以及文件夹Clarification是在比其余部分不同的路径唯一的一个。 我希望它现在更清楚,如果不是,请告诉我。


[编辑最后,我希望]

我想我可以喊“Evrika!”。 你的话“硬编码”让我意识到我必须修改脚本,每当有新的文件夹被添加/删除,所以我想使该数组动态的,如
./script ab "de" g导致array=(ab "de" 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

我想现在我终于可以让脚本做我想做的。 谢谢你,总之,您的答案。

Answer 1:

I really have no idea what you exactly want to achieve! But I had a look at the script you linked in your last edit. Since you have a hard-coded array you might as well instead use an associative array:

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

to loop on the keys of dir_h, i.e., on A B C D E:

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

Try it, this might help you with your "alias" problem (or not).


Here's your script from your other post, using this technique and in a more consistent and readable form (note: I haven't tried it, there might be some minor typos, let me know if it's the case):

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

From this you can do a lot, and have pretty much infinite "alias" handling possibilities.



Answer 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


Answer 3:

你并不需要在这里别名。 只需设置变量S到您的字符串:

S=Supercalifragilistic

然后使用:

./script A B "$S"

要不然打电话给你的脚本直接使用数组:

./script ${DIR[@]}

PS: 这是不使用全部大写在shell变量名的好习惯,你可以不小心覆盖PATH变量的一天。



Answer 4:

你可以这样做:

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

它会替换值“S”与“Supercalifragilistic”阵列中的任何地方。



文章来源: Bash script: internal function alias for longer arguments
标签: bash alias