Bru*_*sky 2 python linux terminal
我见过的大多数代码示例都试图从没有本地回声的stdin读取.为此,他们修改"本地模式"标志以将设置删除为"回声输入字符".我想我可以修改"输入模式"标志TIOCSTI
,用于"在输入队列中插入给定字节"..但是,即使我以root身份运行脚本,它也没有任何效果.我写给fd的任何东西似乎都转到终端输出,而不是终端输入.基本上我想要做的就是这个确切的事情,但在纯粹的python中.
"""
termfake.py
Usage: sudo python termfake.py /dev/ttys002
Get the tty device path of a different local termimal by running `tty`
in that terminal.
"""
import sys
import termios
fd = open(sys.argv[1], 'w')
fdno = fd.fileno()
# Returns [iflag, oflag, cflag, lflag, ispeed, ospeed, cc]
tatters = termios.tcgetattr(fdno)
print('original', tatters)
tatters[0] = termios.TIOCSTI
print('TIOCSTI', termios.TIOCSTI)
# Set iflag
termios.tcsetattr(fdno, termios.TCSANOW, tatters)
# Verify setting change
with open('/dev/ttys002', 'w') as fd2:
print('modified', termios.tcgetattr(fd2.fileno()))
fd.write('This is test\n')
fd.close()
Run Code Online (Sandbox Code Playgroud)
TIOCSTI
是一个ioctl(记录在案tty_ioctl(4)
),而不是终端设置,所以你不能使用tcsetattr()
- 你需要输入假输入的每个字符ioctl()
.从来没有必要从Python做过ioctl,但是以下似乎适用于ls
在运行Bash 的不同终端(指定为参数,例如/ dev/pts/13)中运行:
import fcntl
import sys
import termios
with open(sys.argv[1], 'w') as fd:
for c in "ls\n":
fcntl.ioctl(fd, termios.TIOCSTI, c)
Run Code Online (Sandbox Code Playgroud)
TIOCSTI
需要root权限(或CAP_SYS_ADMIN
更具体,但实际上通常在实践中是相同的) - 请参阅capabilities(7)
.
我从@Ulfalizer 那里得到了答案,并将其扩展为一个完整且可用的应用程序。
import sys
import fcntl
import termios
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('tty', type=argparse.FileType('w'),
help='full tty path as given by the tty command')
group = parser.add_mutually_exclusive_group()
group.add_argument('-n', action='store_true',
help='prevent sending a trailing newline character')
group.add_argument('--stdin', action='store_true',
help='read input from stdin')
group = parser.add_argument_group()
group.add_argument('cmd', nargs='?',
help='command to run (required if not using --stdin)')
group.add_argument('args', nargs='*',
help='arguments to command')
args = parser.parse_known_args()
if args.stdin:
data = sys.stdin.read()
else:
data = ' '.join([args.cmd] + args.args)
for c in data:
fcntl.ioctl(args.tty, termios.TIOCSTI, c)
if not args.n and data[-1][-1] != '\n':
fcntl.ioctl(args.tty, termios.TIOCSTI, '\n')
Run Code Online (Sandbox Code Playgroud)
以下是使用方法:
1号航站楼:做...
$ tty > /tmp/t1
Run Code Online (Sandbox Code Playgroud)
2号航站楼:做...
$ sudo python termfake.py $(cat /tmp/t1) date +%s
Run Code Online (Sandbox Code Playgroud)
终端#1:观察...
$ tty > /tmp/t1
$ date +%s
1487276400
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1512 次 |
最近记录: |