Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux Shell脚本,作为另一个用户杀死_Linux_Tcl_Expect_Bin - Fatal编程技术网

Linux Shell脚本,作为另一个用户杀死

Linux Shell脚本,作为另一个用户杀死,linux,tcl,expect,bin,Linux,Tcl,Expect,Bin,最近,我一直在尝试让这个脚本正常工作: #!/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”的用户身份登录,并通过特定的

最近,我一直在尝试让这个脚本正常工作:

#!/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”,因为事实并非如此。。。
谢谢

我认为运行进程的用户和想要终止进程的用户应该在一个公共组中。进程权限也应该与该组关联。

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

还有其他问题

  • 您可以使用
    nohup
    包装
    kill
    ,但这确实是不必要的,因为发送信号几乎是瞬时的,您不需要额外的复杂性
  • 您正在将密码作为命令行参数传递。这是不安全的,因为任何进程都可以读取传递给任何程序的整个命令行。最好从命令行上命名的文件中提取密码;如果权限设置正确,则只有您(和root用户)可以读取密码(这是确定的)
  • 提取命令行参数时使用
    lrange
    ;这几乎肯定是错误的(如果在Tcl 8.5或更高版本中运行,
    lindex
    命令是更好的选择,甚至可能是
    lassign
    一次提取多个值)
  • 您正在硬编码流程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脚本传递给运行在
su
的shell中。

为什么
nohup kill
kill
命令很快。另外,请使用
[lindex$argv 0]
而不是
[lrange$argv 0]
(除非您确实需要额外的列表引用,如果您的密码包含列表中的重要字符,您可能不需要这样做!)