Domanda

Suppose I have defined an array, like this:

DIR=(A B Supercalifragilistic)

and I need to invoke the script as

./script A B Supercalifragilistic

where the arguments are processed by internal functions func1() and func2(). Is there a way to make an alias (or anything, however it's called) S for Supercalifragilistic so that when I invoke:

./script A B S

the internal functions will process/interpret S as Supercalifragilistic?

Thank you in advance.


[edit]

I should add that the script is invoked via terminal, not inside a script, and the arguments A B Supercalifragilistic, or (hopefully) S, are passed on to the script in the terminal. I'm sorry for the confusion.


[edit2]

The script is here: Bash script: if any argument is "N" then function has extra options , in the answer below. What it does is explained in the OP there, below the script. Finally, instead of DIR=(A B C D E F) it's DIR=(A B Clarification D E F) (it's just an example) and the folder Clarification is the only one in a different path than the rest. I hope it's more clear now, if not, please tell me.


[final edit, I hope]

I think I can shout "Evrika!". Your word "hardcoded" made me realize I have to modify the script anytime a new folder gets added/deleted, so I thought of making the array dynamic, as in
./script a b "d e" g results in array=(a b "d e" g)
but also that it should replace the long paths with some short ones (Clarification >> C), so I made this test script based on also the answers here:

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

and this is what it shows at command prompt:

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

abc
Clarification
d f
e

I think now I can finally make the script to do what I want. Thank you, all, for the answers.

È stato utile?

Soluzione

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.

Altri suggerimenti

No need to use an alias. You could try something like :

$ 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

You don't need alias here. Just set variable S to your string:

S=Supercalifragilistic

and then use:

./script A B "$S"

OR else call your script directly using array:

./script ${DIR[@]}

PS: It is not a good habit to use all caps variable names in shell and you can accidentally overwrite PATH variable some day.

You can do this:

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

It'll replace the value "S" with "Supercalifragilistic" anywhere in the array.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top