了解 tty + bash

3
我发现我可以使用一个Bash会话来按以下方式在另一个会话中打印文本。
echo './myscript' > /dev/pts/0 # assuming session 2 is using this tty
# or
echo './myscript' > /proc/1500/fd/0 # assuming session 2's pid is 1500

但是为什么文本./myscript只打印而不执行呢?我有什么办法可以用这种方式执行我的脚本吗?
(我知道这会引起很多批评,也许会使任何随后的答案充满“别这样做!”但我想这样做的真正原因是自动提供密码给sshfs。我正在使用本地WDMyCloud系统,并且每晚在关闭电源时都会删除我的.authorized_keys文件。)

1
你不能使用FIFO并从中读取密码吗?有什么原因呢? - cEz
@Cez:你的意思是在创建FIFO后将ssh重定向到从中读取吗?像这样ssh myserver < myfifo?根据我的最近经验,似乎ssh命令拒绝从重定向中读取密码。我不确定机制是什么,但我想这是一种安全措施。你有其他了解吗? - JellicleCat
@Cez:我刚刚重复了我认为你提出的实验,使用了我在评论中给出的命令。但它不起作用。 - JellicleCat
我认为任何与ssh相关的应用程序都不会接受来自stdin的密码。你最好自动化密钥复制。 - LMC
1
@JellicleCat 我添加了一个答案,向您展示了我的意思。 - cEz
3个回答

4
为什么文本./myscript只打印而不执行?
输入和输出是两个不同的事情。
向终端写入数据会将数据显示在屏幕上。从终端读取会从键盘读取输入。以任何方式写入终端都不会模拟键盘输入。
输入和输出之间没有固有的耦合,你按下的键在屏幕上显示出来只是一个有意识的设计决策:shell只是读取一个键,然后将其附加到其内部命令缓冲区,并将其副本写入屏幕。
这纯粹是为了你的利益,让你可以看到自己正在输入什么,而不是因为shell在乎屏幕上的内容。由于它并不关心屏幕上的内容,所以向屏幕写更多的东西对shell执行的内容没有影响。
有什么办法可以通过这种方式执行我的脚本吗?
不行,不能通过向终端写入数据来执行脚本。

2

以下是使用FIFO的示例:

#!/usr/bin/bash

FIFO="$(mktemp)"
rm -fv "$FIFO"

mkfifo "$FIFO"

( echo testing123 > "$FIFO" ) &

cat "$FIFO" | sshfs -o password_stdin testing@localhost:/tmp $HOME/tmp

如何存储密码并将其发送到FIFO取决于您。


+1 感谢。我之前不知道 sshfs 中有 password_stdin 选项,因为在 ssh 中它不存在。 - JellicleCat

0

您可以使用ioctl系统调用来实现您想要的功能:

ioctl()系统调用可操作特殊文件的底层设备参数。特别是,许多字符特殊文件(例如终端)的操作特性可以通过ioctl()请求进行控制。

对于此系统调用的'request'参数,您需要使用TIOCSTI,在我的头文件中定义为0x5412。(使用grep -r TIOCSTI /usr/include验证您的环境。)

我在ruby中如下实现:

fd = IO.sysopen("/proc/#{$$}/fd/0", 'wb')
io = IO.new(fd, 'wb')
"puts 9 * 16\n".chars.each { |c| io.ioctl 0x5412, c };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接