使用 #!/bin/bash 脚本

gas*_*per 0 ubuntu bash sed

我正在尝试开发一个脚本来自动在我的服务器上设置一个新的虚拟主机域,我在我的服务器上有一个自定义设置,它为每个域提供用户名和密码,但没有外壳访问权限。(这是使用系统用户对 vsftpd 所做的)它还在 /var/www/sites/"domainname.com" 中创建一个目录,其中包含所有默认文件。然后为虚拟主机创建了一个 /etc/apache2/sites-available/domaindname.com Apache Conf 文件。这个脚本出错了,但看起来好像完成了所有事情。不过,我希望错误消失。

#!/bin/bash
#\
args=("$@")
# Copy Site Hosting Directory
cp -a /var/www/sites/skeleton /var/www/sites/${args[0]}

# Copy Apache Config File
cp -a "/etc/apache2/sites-available/skeleton" "/etc/apache2/sites-available/$1"

# Replace 'skeleton' with '$1' in config file
sed -i "s/skeleton/$1/g" /etc/apache2/sites-available/$1

# Create User
useradd -d /var/www/sites/$1 -s /usr/sbin/nologin $1

chown -R $1:www-data /var/www/sites/$1
chmod -R 0775 /var/www/sites/$1

# Set new password for user
exec expect -f $0 ${1+"$@"}
set password [lindex $argv 1]
spawn passwd [lindex $argv 0]
sleep 1
expect "assword:"
send "$password\r"
expect "assword:"
send "$password\r"
expect eof
Run Code Online (Sandbox Code Playgroud)

我得到的错误信息是:

can't read "args[0]": no such variable
    while executing
"cp -a /var/www/sites/skeleton /var/www/sites/${args[0]}"
    (file "./test" line 5)
Run Code Online (Sandbox Code Playgroud)

脚本解决方案:(感谢serverfault用户的帮助)

#!/bin/bash

# Copy Site Hosting Directory
cp -a /var/www/sites/skeleton /var/www/sites/$1

# Copy Apache Config File
cp -a "/etc/apache2/sites-available/skeleton" "/etc/apache2/sites-available/$1"

# Replace 'skeleton' with '$1' in config file
sed -i "s/skeleton/$1/g" /etc/apache2/sites-available/$1

# Create User
useradd -d /var/www/sites/$1 -s /usr/sbin/nologin $1

chown -R $1:www-data /var/www/sites/$1
chmod -R 0775 /var/www/sites/$1

# Set new password for user
# /usr/bin/expect -f $0 ${1+"$@"}
expect -c "
    spawn passwd $1
    sleep 1
    expect \"assword:\"
    send \"$2\r\"
    expect \"assword:\"
    send \"$2\r\"
    expect eof
    "
Run Code Online (Sandbox Code Playgroud)

问题是期望正在对自身进行递归调用,但该文件是混合的 bash 和期望脚本。所以解决方案是用-c(要解析和执行的字符串)调用expect

lar*_*sks 9

由于您尚未发布错误消息,因此我只是在这里进行了有根据的猜测。您的脚本执行以下操作:

# Set new password for user
exec expect -f $0 ${1+"$@"}
Run Code Online (Sandbox Code Playgroud)

这会调用 expect 脚本的完整路径作为参数传递给 expect 的“-f”选项……这意味着 expect 将从脚本的顶部开始执行,而不是从紧跟在 exec 语句之后的“set”行开始执行.

这将立即导致语法错误,因为该脚本是一个 shell 脚本,而不是一个期望脚本。

您可能希望将 expect 脚本移动到一个单独的文件中,然后显式调用它:

exec expect -f my-expect-script ${1+"$@"}
Run Code Online (Sandbox Code Playgroud)

此外,这不是您的问题的主要内容,您的脚本使用位置变量(例如,“$1”)以及您在脚本顶部初始化的 $args 列表。你正在以两种不同的方式有效地做同样的事情,这在某些时候会导致混乱和沮丧。