bash 脚本内嵌 expect 脚本并传递参数

前情提要:

  1. 多台机器要登录 root 用户执行命令;
  2. 系统中只有 su 命令和 expect 能用,没有 sudo ;
  3. 不能动 pam.d 来免密;
  4. ssh 不能 root 登录

于是想了一晚上,用一种 dirty 的方式完成了这个操作:

eval "export LANG=C; expect -c 'spawn su -l "${su_user:-root}" -c \"$(readlink -f $0) ${args}"\" ; expect Password:; send "${su_pass}"\r; interact;'"

解释一下:

  1. 使用 expect -c 这种方式可以在 bash 脚本中嵌入 expect 脚本,但是这种方法不能给 expect 传递参数(主要是传登录密码);
  2. 但是可以把 bash 变量混杂在 expect 命令中,拼凑出一个字符串,然后交给 eval 去执行;
  3. 最后实现脚本用 root 权限执行自己。