Bash 脚本将文件复制到用户的(通配符)主目录

Ign*_*ška 3 cp shell-script wildcards tilde

/root/nbu/file1.sh如果用户的 id 是偶数,我需要复制到每个用户的主目录。

尝试执行以下脚本:

#!/bin/bash
cat /etc/passwd | while read LINE
do
    username=$(awk -v var="$LINE" -F: '{
        if ($3 % 2 == 0)
           print $1
        }')
    cp /root/nbu/file1.sh ~"$username"
done
Run Code Online (Sandbox Code Playgroud)

它什么都不做。如果我回显cp /root/nbu/file1.sh ~"$username"命令并直接在脚本中执行它,它就可以工作。

我想问题是~在 bash 脚本中得到了扩展,但不知道如何解决这个问题。

先感谢您。

ilk*_*chu 7

如果引用用户名部分,波浪号扩展不起作用:

$ echo ~root ~"root"
/root ~root
Run Code Online (Sandbox Code Playgroud)

(无论如何,它发生在变量扩展之前。)

但是,既然您已经passwd在 shell 中阅读了,为什么不完全这样做:

#!/bin/bash
getent passwd | while IFS=: read -r user pass uid gid gecos home shell; do 
    if (( uid % 2 == 0 )); then
        echo "uid $uid of user '$user' is even and their home is '$home'";
    fi; 
done
Run Code Online (Sandbox Code Playgroud)

如果您的系统有getent,最好使用它,而不是/etc/passwd直接使用它。

另一方面,由于您似乎不需要任何用户名,您可以让awk脚本输出目录( $6)。


Jef*_*ler 6

那是因为波浪号扩展发生在变量扩展之前

展开的顺序是:大括号展开;波浪号扩展、参数和变量扩展、算术扩展和命令替换(以从左到右的方式完成);分词;和文件名扩展。

echo结果看起来是正确的,如果您重新评估它也可以工作,但是对于脚本,您需要以不同的方式进行。也许:

# ...
homedir=$(getent passwd "$username" | cut -d: -f6)
cp /root/nbu/file1.sh "$homedir"
# ...
Run Code Online (Sandbox Code Playgroud)