1

最近我一直试图让这个脚本工作:

#!/usr/bin/expect -f
set pssword [lrange $argv 0 0]
spawn su - kod -c cd cod4 -c "nohup kill 7938"  > /dev/null 2>&1 &
expect "Password:" { send "$pssword\r" }
expect "# " { send "q" }
exit

它应该以名为“kod”的用户身份登录并通过某个 pid 终止进程

这是启动脚本,它工作得很好......

#!/usr/bin/expect -f
set pssword [lrange $argv 0 0]
set port [lrange $argv 1 1]
set mod [lrange $argv 2 2]
set map [lrange $argv 3 3]
set num [lrange $argv 4 4]
set hostname [lrange $argv 5 5]
set rcon [lrange $argv 6 6]
set password [lrange $argv 7 7]
spawn su - kod -c cd cod4 -c "nohup ./cod4_lnxded +set s_num=$num +set net_port $port +set dedicated 2 +set fs_game mods/$mod +set sv_punkbuster 1 +set sv_hostname $hostname +set rcon_password $rcon +set g_password $password +set promod_mode match_mr10 +set g_gametype sd +map $map"  > /dev/null 2>&1 &
expect "Password:" { send "$pssword\r" }
expect "# " { send "q" }
exit

请不要告诉我“以 root 身份登录”或“只使用 sudo”,因为事实并非如此......谢谢!

4

2 回答 2

0

真正的问题是您的代码正在删除可能来自该(相当复杂的)命令的任何错误消息;如果您要立即打印该信息或将其记录到文件中,那会好得多。这样,您可以诊断问题,而不必胡乱猜测……</p>

还有其他问题。

  • 您将 with 包装kill起来nohup,但这确实是不必要的,因为发送信号几乎是瞬时的,并且您不想要额外的复杂性。
  • 您将密码作为命令行参数传递。这是不安全的,因为任何进程都可以读取传递给任何程序的整个命令行。最好从命令行命名的文件中提取密码;如果您设置了权限,那么只有您(和 root)可以读取密码(没关系)。
  • lrange在提取命令行参数时使用;那是……几乎可以肯定是错误的(该lindex命令是更好的选择,或者甚至可能lassign一次提取多个值,前提是它在 Tcl 8.5 或更高版本中运行)。
  • 您正在对进程 ID 进行硬编码。这几乎肯定不是您想要做的,因为随着时间的推移它完全可能会有所不同。

对那一点点进行排序,我得到了这个可能的改进脚本:

#!/usr/bin/expect -f

# A more robust method for handling arguments than you had...
if {$argc == 0} {
    error "usage: $argv0 pid ?passFile?"
}
set pid [lindex $argv 0]
if {$argc > 1} {
    set passwordFile [lindex $argv 1]
} else {
    # Sensible default
    set passwordFile ~/.codPassword
}

# Read the password from the file
set f [open $passwordFile]
gets $f pssword
close $f

# Run the program (doesn't need the 'cd') with trap to supply password,
# and connect to user for error passthrough
spawn su - kod -c kill $pid
expect_background {
    "Password:" {exp_send "$pssword\r"}
}
interact {eof close}

再想一想,问题提出后很久,另一个问题是这样的:

spawn su - kod -c cd cod4 -c "nohup kill 7938"  > /dev/null 2>&1 &

这极有可能是在做一些奇怪和意想不到的事情。相反,您可能需要这个:

spawn su -c "cd cod4; nohup kill 7938 > /dev/null 2>&1 &" - kod

那是因为您想将所有这些作为单个 shell 脚本传递,以便在运行的 shell 中su运行。

于 2011-09-27T08:52:38.957 回答
0

我认为运行该进程的用户和想要杀死它的用户应该在一个共同的组中。进程权限也应该与该组相关联。

于 2011-08-13T11:20:45.713 回答