bash 向后台进程发送命令

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5998126/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 20:30:49  来源:igfitidea点击:

Send command to a background process

bashprocess

提问by Mohit Deshpande

I have a previously running process (process1.sh) that is running in the background with a PID of 1111 (or some other arbitrary number). How could I send something like command option1 option2to that process with a PID of 1111?

我有一个以前运行的进程 (process1.sh),它在后台运行,PID 为 1111(或其他任意数字)。我怎么能用command option1 option21111 的 PID 向那个进程发送类似的东西?

I don'twant to start a new process1.sh!

并不想开始一个新的process1.sh!

采纳答案by haknick

Named Pipes are your friend. See the article Linux Journal: Using Named Pipes (FIFOs) with Bash.

命名管道是你的朋友。请参阅文章Linux Journal:在 Bash 中使用命名管道 (FIFO)

回答by user

Based on the answers:

基于以下答案:

  1. Writing to stdin of background process
  2. Accessing bash command line args $@ vs $*
  3. Why my named pipe input command line just hangs when it is called?
  4. Can I redirect output to a log file and background a process at the same time?
  1. 写入后台进程的标准输入
  2. 访问 bash 命令行参数 $@ 与 $*
  3. 为什么我的命名管道输入命令行在调用时挂起?
  4. 我可以同时将输出重定向到日志文件和后台进程吗?

I wrote two shell scripts to communicate with my game server.

我写了两个 shell 脚本来与我的游戏服务器通信。



This first script is run when computer start up. It does start the server and configure it to read/receive my commands while it run in background:

第一个脚本在计算机启动时运行。它确实启动了服务器并将其配置为在后台运行时读取/接收我的命令:

start_czero_server.sh

start_czero_server.sh

#!/bin/sh

# Go to the game server application folder where the game application `hlds_run` is
cd /home/user/Half-Life

# Set up a pipe named `/tmp/srv-input`
rm /tmp/srv-input
mkfifo /tmp/srv-input

# To avoid your server to receive a EOF. At least one process must have
# the fifo opened in writing so your server does not receive a EOF.
cat > /tmp/srv-input &

# The PID of this command is saved in the /tmp/srv-input-cat-pid file
# for latter kill.
# 
# To send a EOF to your server, you need to kill the `cat > /tmp/srv-input` process
# which PID has been saved in the `/tmp/srv-input-cat-pid file`.
echo $! > /tmp/srv-input-cat-pid

# Start the server reading from the pipe named `/tmp/srv-input`
# And also output all its console to the file `/home/user/Half-Life/my_logs.txt`
#
# Replace the `./hlds_run -console -game czero +port 27015` by your application command
./hlds_run -console -game czero +port 27015 > my_logs.txt 2>&1 < /tmp/srv-input &

# Successful execution 
exit 0


This second script it just a wrapper which allow me easily to send commands to the my server:

这第二个脚本只是一个包装器,它允许我轻松地将命令发送到我的服务器:

send.sh

发送.sh

half_life_folder="/home/Hyman/Steam/steamapps/common/Half-Life"

half_life_pid_tail_file_name=hlds_logs_tail_pid.txt
half_life_pid_tail="$(cat $half_life_folder/$half_life_pid_tail_file_name)"

if ps -p $half_life_pid_tail > /dev/null
then
    echo "$half_life_pid_tail is running"
else   
    echo "Starting the tailing..."
    tail -2f $half_life_folder/my_logs.txt &
    echo $! > $half_life_folder/$half_life_pid_tail_file_name
fi

echo "$@" > /tmp/srv-input
sleep 1

exit 0

Now every time I want to send a command to my server I just do on the terminal:

现在每次我想向我的服务器发送命令时,我只需在终端上执行:

./send.sh mp_timelimit 30

This script allows me to keep tailing the process you may current terminal, because every time I send a command, it checks whether there is a tail process running in background. If not, it just start one and every time the process sends outputs, I can see it on the terminal I used to send the command, just like for the applications you run appending the &operator.

这个脚本允许我继续跟踪当前终端的进程,因为每次我发送命令时,它都会检查是否有后台运行的尾进程。如果没有,它只是启动一个,每次进程发送输出时,我都可以在我用来发送命令的终端上看到它,就像你运行的应用程序附加&操作符一样。



You could always keep another open terminal open just to listen to my server server console. To do it just use the tailcommand with the -fflag to follow my server console output:

你总是可以打开另一个打开的终端,只是为了收听我的服务器控制台。要做到这一点,只需使用tail带有-f标志的命令来跟随我的服务器控制台输出:

./tail -f /home/user/Half-Life/my_logs.txt

回答by Andre Holzner

If you don't want to be limited to signals, your program must support one of the Inter Process Communication methods. See the corresponding Wikipedia article.

如果您不想局限于信号,您的程序必须支持进程间通信方法之一。请参阅相应的维基百科文章

A simple method is to make it listen for commands on a Unix domain socket.

一个简单的方法是让它监听Unix 域套接字上的命令。

回答by jm666

You can use the bash's coproccomamnd. (avaliable only in 4.0+) - it's like ksh's |&

您可以使用 bash 的命令coproc。(仅在 4.0+ 中可用)- 就像 ksh 的一样|&

check this for examples http://wiki.bash-hackers.org/syntax/keywords/coproc

检查这个例子http://wiki.bash-hackers.org/syntax/keywords/coproc

回答by nhed

you can't send new args to a running process.

您不能将新的 args 发送到正在运行的进程。

But if you are implementing this process or its a process that can take the args from a pipe, then the other answer would help.

但是,如果您正在实施此过程或其可以从管道中获取 args 的过程,那么另一个答案会有所帮助。