是否有任何智能的功能?重定向扭曲我可以做一个cronjob来每天在固定时间发送该stop命令吗?
#1 楼
这个答案不能解决问题,但是留在这里是因为30多个人发现它很有用,否则我早就删除了它。写到
/proc/*pid of the program*/fd/0
。 fd
子目录包含所有打开的文件的描述符,文件描述符0
是标准输入(1是stdout,2是stderr)。您可以使用它在程序所在的tty上输出消息。正在运行,尽管它不允许您写入程序本身。
示例
[ciupicri@hermes ~]$ cat
shows on the tty but bypasses cat
端子2:
[ciupicri@hermes ~]$ pidof cat
7417
[ciupicri@hermes ~]$ echo "shows on the tty but bypasses cat" > /proc/7417/fd/0
#2 楼
基于屏幕的解决方案像这样启动服务器:
# screen -d -m -S ServerFault tr a-z A-Z # replace with your server
屏幕将以分离模式启动,因此,如果您要查看发生的情况,运行:
# screen -r ServerFault
像这样控制服务器:
# screen -S ServerFault -p 0 -X stuff "stop^M"
# screen -S ServerFault -p 0 -X stuff "start^M"
# screen -S ServerFault -p 0 -X stuff "^D" # send EOF
(此答案基于发送文本输入到Unix&Linux兄弟站点的分离屏幕上)
参数说明:
-d -m
Start screen in "detached" mode. This creates a new session but doesn't
attach to it. This is useful for system startup scripts.
-S sessionname
When creating a new session, this option can be used to specify a meaningful
name for the session.
-r [pid.tty.host]
-r sessionowner/[pid.tty.host]
resumes a detached screen session.
-p number_or_name|-|=|+
Preselect a window. This is useful when you want to reattach to a specific
window or you want to send a command via the "-X" option to a specific
window.
-X
Send the specified command to a running screen session e.g. stuff.
东西[字符串]
Stuff the string string in the input buffer of the current window.
This is like the "paste" command but with much less overhead. Without
a parameter, screen will prompt for a string to stuff.
基于tmux的解决方案
像这样启动服务器:
# tmux new-session -d -s ServerFault 'tr a-z A-Z' # replace with your server
tmux将以分离模式启动,因此,如果要查看发生了什么,请运行:
# tmux attach-session -t ServerFault
像这样控制服务器:
# tmux send-keys -t ServerFault -l stop
# tmux send-keys -t ServerFault Enter
# tmux send-keys -t ServerFault -l start
# tmux send-keys -t ServerFault Enter
# tmux send-keys -t ServerFault C-d # send EOF
参数说明:
new-session [-AdDP] [-c start-directory] [-F format] [-n window-name] [-s
session-name] [-t target-session] [-x width] [-y height]
[shell-command]
Create a new session with name session-name.
The new session is attached to the current terminal unless -d is
given. window-name and shell-command are the name of and shell
command to execute in the initial window. If -d is used, -x and
-y specify the size of the initial window (80 by 24 if not
given).
send-keys [-lR] [-t target-pane] key ...
(alias: send)
Send a key or keys to a window. Each argument key is the name of
the key (such as `C-a' or `npage' ) to send; if the string is not
recognised as a key, it is sent as a series of characters. The
-l flag disables key name lookup and sends the keys literally.
评论
这是真正的解决方案:)
– jackcogdill
20-2-20在20:07
#3 楼
可以在不运行screen
实用程序或任何其他实用程序的情况下将输入文本发送到正在运行的进程。可以通过将输入文本发送到流程的标准输入“文件” /proc/PID#/fd/0
来完成。但是,需要以一种特殊的方式发送输入文本,以供流程读取。通过常规文件write
方法发送输入文本将不会导致进程接收文本。这是因为这样做只会附加到“文件”,而不会触发进程读取字节。要触发进程读取字节,必须执行
IOCTL
操作对于每个要发送的字节,其类型为TIOCSTI
。这会将字节放入进程的标准输入队列中。这里将用C,Perl和Python中的一些示例进行讨论:
https:// unix。 stackexchange.com/questions/48103/construct-a-command-by-puting-a-string-into-a-tty/48221
-
所以要回答最初的问题将在9年前问到,cron作业将需要运行一些小型实用程序脚本/程序,类似于人们为另一个问题编写的示例,这会将字符串“ stop \ n”发送到该问题中的服务器进程,通过
IOCTL
类型的TIOCSTI
操作发送5个字节中的每个字节。当然,这仅在支持
TIOCSTI
IOCTL
操作类型的系统(例如Linux)上有效,并且仅适用于root
用户帐户,因为/proc/
下的这些“文件”由root
“拥有”。#4 楼
尝试以下操作开始:# screen
# cd /path/to/wd
# mkfifo cmd
# my_cmd <cmd
C-A d
要杀死它:
# cd /path/to/wd
# echo "stop" > cmd
# rm cmd
评论
很好,但是它可能具有程序运行时无法发送其他命令的缺点。如果程序在stdin上达到EOF时停止,则在第一个回显“ xxx”> cmd时程序将停止(因为管道将关闭)。尽管有些程序很聪明,当遇到EOF时可以重新打开(rewind(3))其stdin。
–克里斯蒂安·丘皮图
2010-09-06 12:30
#5 楼
由于我无法评论(2010年)克里斯蒂安·丘皮图(Cristian Ciupitu)的最普遍接受的答案,因此我必须将其放在一个单独的答案中:此问题已经在以下线程中解决:https://stackoverflow.com / questions / 5374255 /如何将数据写入到现有的处理程序-stdin-from-external-process
总之:
您必须开始使用stdin的管道进行处理,该管道在写入当前输入时不会阻塞也不关闭。这可以通过一个简单的无限循环来实现,该循环将通过管道传递到有问题的过程中:
$ (while [ 1 ]; do sleep 1; done) | yourProgramToStart
我可以确认这与krissi打开管道的方式不同在我的情况下不起作用。所示的解决方案确实起作用了。
然后您可以写入该进程的... / fd / 0文件,以向其发送指令。唯一的缺点是,您还需要终止bash进程,该进程在服务器关闭后仍会执行无限循环。
#6 楼
如果它对任何人都有帮助:我有一个类似的问题,并且由于我使用的过程不在
screen
或tmux
之下,所以我不得不采用其他方法。我附加了
gdb
到运行我的进程的xterm
,并使用来自call write(5, "stop\n", 5)
的gdb
写入主pty文件描述符。通过查看
/proc/<pid>/fd
到/dev/ptmx
的链接,然后找出了将数据发送到哪个文件描述符两种选择之间的反复试验(将我的字符串发送到两个匹配的文件描述符似乎没有造成任何损害)。编辑
结果发现我附加了
xterm
进程是通过键绑定中的spawn-new-terminal()
xterm
操作产生的,而第二个ptmx
打开的文件描述符只是尚未关闭的父ptmx
进程的xterm
。因此,反复试验和错误调用已将输出发送给其他终端。
大多数
xterm
进程没有两个ptmx
fi文件描述符。END EDIT
这样可以有效地将字符串键入终端,然后将其发送到在其下运行的进程。
b您可能需要允许使用
sudo bash -c "echo 0 > /proc/sys/kernel/yama/ptrace_scope"
之类的东西附加到正在运行的进程中
评论
@James Lawrie:然后看看proc(5)和proc.txt。
–克里斯蒂安·丘皮图
10-9-6 '12:46
+2,无论您认为了解多少,总会有更多要学习的知识:)流畅。
–user15590
2010-09-06 14:55
请注意,尽管proc fd仅重定向到用作stdin的源。在您的示例中,如果您在终端1中输入内容,它将再次打印出该内容(将其发送到cat stdin并由cat打印),从而导致您两次看到该内容。另一方面,如果您将某些内容发送到fd / 0,它将被发送到控制台,但不会发送到cat,因此仅显示一次。由于在这个示例中cat仅简单地再次打印了输入内容,因此您无法真正看到是否正在打印输入或输出,因此产生了这种误解。 / fd / 0指向控制台/ pts;参见ls -l / proc / 7417 / fd / 0。
–木崎
13年7月2日在10:09
实际示例:我已经启动了gphoto2 --get-all-files,它要求进行100次确认。当我回显“ y”> / proc / PID / fd / 0时,gphoto2无法继续,但是,在终端中打印了“ y”。
–瑟斯登·斯塔克
15年5月25日在7:50
@ThorstenStaerk,我知道,这就是我添加该注释的原因。您只在写入与gphoto2运行的终端相对应的设备文件(例如/ dev / pts / 19),y字符不会到达应用程序本身。这类似于使用write(1)命令时发生的情况。无论如何,请尝试我的其他答案或图形自动化工具(如xdotool)。
–克里斯蒂安·丘皮图
15年5月25日在20:05