理解tty + bash:跨bash会话执行脚本的疑问与解决方法
问题解析与解决方案
嘿,这个场景我太懂了——跨会话发送命令只显示不执行,核心原因其实很简单,咱们一步步拆解清楚:
为什么只打印./myscript不执行?
当你把字符串发送到另一个bash会话时,本质只是把内容追加到了那个会话的输入缓冲区,就像你手动在终端敲了这几个字符,但没按下回车键触发执行。而且如果目标会话当时正忙(比如在跑别的命令),或者处于非交互状态,输入根本不会被bash处理。
怎么让脚本真正执行?
如果一定要跨会话触发执行,或者更直接地解决sshfs自动输密码的问题,这里有几个实用方案:
方案1:用screen/tmux管理会话(跨会话执行命令)
如果你的目标bash会话是用screen或tmux创建的,那就可以直接向会话发送带回车的命令:
- 对于screen:
这里的screen -S 你的会话名 -X stuff "./myscript\n"\n就是模拟按下回车键,让bash执行输入的命令。 - 对于tmux:
tmux send-keys -t 你的会话名 "./myscript" EnterEnter参数会自动模拟回车动作。
方案2:直接解决sshfs自动输密码的问题(更推荐)
跨会话操作其实绕远路了,针对sshfs自动输密码,有更直接的工具:
用sshpass(最简单)
如果你的WDMyCloud支持安装sshpass(可以试试apt-get install sshpass,或者手动编译),直接用:
# 明文密码(不推荐,有安全风险) sshpass -p "你的密码" sshfs 用户名@主机:/远程路径 /本地挂载点 # 更安全:把密码放在文件里(文件权限设为600) sshpass -f /path/to/密码文件 sshfs 用户名@主机:/远程路径 /本地挂载点
用expect脚本(兼容性更好)
如果装不了sshpass,写个expect脚本模拟手动输密码:
#!/usr/bin/expect -f set password "你的密码" # 替换成你的sshfs命令 spawn sshfs 用户名@主机:/远程路径 /本地挂载点 # 等待密码提示(根据实际提示调整,比如可能是"Password:") expect "password:" # 发送密码+回车 send "$password\r" # 保持交互(如果需要) interact
给脚本加执行权限:chmod +x mount_sshfs.exp,然后运行./mount_sshfs.exp就行。
方案3:解决WDMyCloud删authorized_keys的根源问题
既然每天都会删,不如直接定时恢复:
- 把你的公钥备份到WDMyCloud的非系统目录,比如
/mnt/HD/HD_a2/my_backups/authorized_keys - 写个恢复脚本
restore_keys.sh:#!/bin/bash BACKUP_KEY="/mnt/HD/HD_a2/my_backups/authorized_keys" KEY_PATH="/home/你的用户名/.ssh/authorized_keys" cp $BACKUP_KEY $KEY_PATH chmod 600 $KEY_PATH chown 你的用户名:你的用户名 $KEY_PATH - 给脚本加执行权限,然后用cron每天自动执行:
运行crontab -e,添加一行:
这会每天凌晨3点自动恢复你的authorized_keys,之后ssh/sshfs就能免密登录了。0 3 * * * /path/to/restore_keys.sh
内容的提问来源于stack exchange,提问作者Jellicle




