循环遍历作为参数给出的 shell 数组

循环遍历作为参数给出的 shell 数组

我正在尝试编写一个小帮助程序脚本,该脚本将更改服务器上某些站点的权限和所有权。

现在,我可以传入 1 个站点,也可以通过简单地跳过该参数来完成所有操作。

我发现我需要能够应用于服务器上的多个站点,但不是全部,所以我尝试通过以下方式传递数组:

SLIST=("my.site.com" "your.site.com")
./website-perms 644 755 kevin "${SLIST[@]}"

但是,它只执行数组中的第一项my.site.com

如何解决这个问题以便我可以传递一系列站点?

完整代码

#!/bin/bash

# Done nightly, and copied to /usr/bin/
if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root" 1>&2
   exit 1
fi
if [ $# -eq 0 ]; then
    echo "usage: ./website-perms.sh fileperm folderperm owner (1|2) (1=kevin,2=www-data) (optional) Site Array"
    exit 1
fi

function chg_perms() {
    echo "find $1 -type f -exec chmod $2 {} \\";
    echo "find $1 -type d -exec chmod $3 {} \\";
    find $1 -type f -exec chmod $2 {} \;
    find $1 -type d -exec chmod $3 {} \;
    echo "-- chg_perms done";
}

function chg_owner() {
    echo "chown -R $2:www-data $1";
    chown -R $2:www-data $1;
    echo "-- chg_owner done";
}

SITES=$4;
if [ -z $SITES ]; then
    for dir in /var/www/httpdocs/*/
    do
        dir=${dir%*/}
        chg_perms "/var/www/httpdocs/${dir##*/}" $1 $2
        chg_owner "/var/www/httpdocs/${dir##*/}" $3
    done;
else
    for dir in "${SITES[@]}" #ONLY DOES THE FIRST ITEM
    do
        chg_perms "/var/www/httpdocs/$dir" $1 $2
        chg_owner "/var/www/httpdocs/$dir" $3
    done
fi;

答案1

不错的剧本。通常我会使用所有剩余的参数作为站点列表。像这样的东西(我还没有测试过这些模组):

if [ $# -lt 3 ]; then
    echo >&2 "usage: $0 fileperm folderperm owner [site ...]"
    exit 1
fi

[。 。 。 ]

fileperm="$1"
folderperm="$2"
owner="$3"
shift 3             # shift first 3 args off of list

if [ $# -eq 0 ]; then
    for dir in /var/www/httpdocs/*/    #stackexchange syntax coloring fix*/
    do
        dir="${dir%/*}"
        chg_perms "/var/www/httpdocs/${dir##*/}" "$fileperm" "$folderperm"
        chg_owner "/var/www/httpdocs/${dir##*/}" "$owner"
    done;
else
    for dir           # step through positional args ($1,$2,...,$N)
    do
        chg_perms "/var/www/httpdocs/$dir" "$fileperm" "$folderperm"
        chg_owner "/var/www/httpdocs/$dir" "$owner"
    done
fi

答案2

尽管我更喜欢 RobertL 的方法,但略有不同

sites=( "${@:4}" )
# ...
for dir in "${sites[@]}"; do ...
  • 要声明数组,必须使用括号。
  • "${@:4}"获取位置参数,从 $4 开始直到结束。
  • 改掉使用 ALLCAPSVARNAMES 的习惯:将它们限制为仅用于 shell。

相关内容