我已经下载了expect5.4。我正在尝试为运行精简版 linux 的 ARM(PandaBoard) 交叉编译它。
在配置的初始设置中,我尝试
Shell$ ./configure --host=ARM
configure: WARNING: If you wanted to set the --build type, don't use --host.
If a cross compiler is detected then cross compile mode will be used.
checking for correct TEA configuration... ok (TEA 3.9)
configure: configuring expect 5.45
checking for Tcl configuration... found /home/user1/scripts/tcl8.6.0/unix/tclConfig.sh
checking for existence of /home/user1/scripts/tcl8.6.0/unix/tclConfig.sh... loading
configure: --prefix defaulting to TCL_PREFIX /usr/local
configure: --exec-prefix defaulting to TCL_EXEC_PREFIX /usr/local
checking for ARM-gcc... /home/user1/toolchain/toolchain/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-gcc
checking for C …Run Code Online (Sandbox Code Playgroud) 我想设置rsync我的服务器的备份,所以我运行以下命令
rsync -r -e ssh --rsync-path="sudo rsync" rsyncuser@example.com:/ /backup/
Run Code Online (Sandbox Code Playgroud)
理想情况下,该命令会询问我的私人 ssh 密钥密码,然后连接,然后询问 rsyncuser 的 sudo 密码,然后在服务器上运行 rsync。但我得到了臭名昭著的错误:
sudo: no tty present and no askpass program specified
Run Code Online (Sandbox Code Playgroud)
所以我不得不将它添加到/etc/sudoers(使用sudo visudo),这基本上为用户提供了对系统的无密码完全读写访问权限rsyncuser,这不合我的口味:
rsyncuser ALL= NOPASSWD:/usr/bin/rsync
Run Code Online (Sandbox Code Playgroud)
我该如何告诉 sudo 从另一个 TTY 读取其密码?
这样,我可以rsync在本地机器上的一个终端窗口中运行,并使用另一个终端窗口打开一个(可能是单独的)与服务器的 ssh 连接,并在那里提供 sudo 密码。
我想到做这样的事情的唯一方法是expect在 sudo 周围使用脚本,它从命名管道中读取密码,然后我会从另一个终端写入该管道。
注意:这更多是为了实验和学习,而不是为了任何实际目的,我不是想找出如何将 sudo 与 rsync 一起使用,我已经阅读了我能找到的所有相关内容。
我编写了登录远程机器并在那里运行一些脚本的期望脚本但我还需要验证以下内容
验证目录是否/var/cti/adm/APP存在。
如果adm目录下不存在APP ,则需要创建此目录并为该目录添加所有权,(作为chown系统)
请建议如何检查expect脚本中是否存在目录,如果不需要创建此目录
我的期望脚本的一部分示例
#!/usr/bin/expect -f
set multiPrompt {[#>$]}
send "ssh $LOGIN3@$IP\r"
sleep 0.5
expect {
word: {send $PASS\r ; exp_continue }
expect -re $multiPrompt
}
Run Code Online (Sandbox Code Playgroud)
例如我们如何用 bash 做到这一点
[[ ! -d /.../..../... ]] && mkdir -p xxxxx
Run Code Online (Sandbox Code Playgroud) 考虑这个交互式脚本:
#!/usr/bin/env bash
set -eu
while true; do
read -p '> '
if [ "$REPLY" == quit ]; then
break
fi
echo "'$REPLY'"
done
Run Code Online (Sandbox Code Playgroud)
现在我想expect与它交互:
#!/usr/bin/env bash
set -eu
echo '
spawn ./1.sh
expect >
send cmd1\n
expect {\n> }
send quit\n
' | expect -d
Run Code Online (Sandbox Code Playgroud)
但当我运行它时,它说:
...
expect: does " cmd1\r\n'cmd1'\r\n> " (spawn_id exp6) match glob pattern "\n> "? no
expect: timed out
send: sending "quit\n" to { exp6 }
Run Code Online (Sandbox Code Playgroud)
为什么不匹配?如何检测新提示的出现(完成命令)?
如果我执行脚本
#!/usr/bin/expect
set pass [lindex $argv 0]
spawn encfs -v {CRIPT_DIR} {MNT_DIR} -o nonempty
expect "*EncFS Password:*"
send "$pass\r"
expect eof
Run Code Online (Sandbox Code Playgroud)
期望脚本输出:
zz@zz-com:/media/truecrypt5/mmm$./e.sh 1
spawn encfs -v /media/truecrypt5/mmm/cr /media/truecrypt5/mmm/mn -o nonempty
10:25:11 (main.cpp:523) Root directory: /media/truecrypt5/mmm/cr/
10:25:11 (main.cpp:524) Fuse arguments: (daemon) (threaded) (keyCheck) encfs /media/truecrypt5/mmm/mn -o nonempty -s -o use_ino -o default_permissions
10:25:11 (FileUtils.cpp:177) version = 20
10:25:11 (FileUtils.cpp:181) found new serialization format
10:25:11 (FileUtils.cpp:199) subVersion = 20100713
10:25:11 (Interface.cpp:165) checking if ssl/aes(3:0:2) implements ssl/aes(3:0:0)
10:25:11 (SSL_Cipher.cpp:370) allocated cipher ssl/aes, …Run Code Online (Sandbox Code Playgroud) 我只是在改进我的问题,因为到目前为止我已经做到了:
set username [lindex $argv 0]
set password [lindex $argv 1]
set hostname [lindex $argv 2]
if {[llength $argv] == 0} {
send_user "Usage: scriptname username \'password\' hostname\n"
exit 1
}
send_user "\n#####\n# $hostname\n#####\n"
spawn ssh -q -o StrictHostKeyChecking=no $username@$hostname
expect {
timeout { send_user "\nFailed to get password prompt\n"; exit 1 }
eof { send_user "\nSSH failure for $hostname\n"; exit 1 }
"Password: "
}
send "$password\r"
expect {
timeout { send_user "\nLogin failed. Password incorrect.\n"; exit 1}
"{severname:mike} …Run Code Online (Sandbox Code Playgroud) 当我从 bash 运行我的 SSHFS 连接脚本时,一切正常。
但是,当我使用该expect实用程序运行相同的脚本时,当我尝试访问文件夹安装位置时出现以下错误:
Transport endpoint is not connected
Run Code Online (Sandbox Code Playgroud)
这是我的期望脚本:
#!/usr/bin/expect -f
spawn standard_sshfs_connection_string_or_script
expect "password: "
send "my_password\r"
Run Code Online (Sandbox Code Playgroud)
问:有什么想法吗?
笔记:
fusermount -u mount_locationspawn创建新进程的事情,也许 sshfs 进程过早关闭?(有没有办法确保 sshfs 进程保持打开状态?)expect -c 'spawn scp -C -o CompressionLevel=9 ~/partFiles/* abc@10.200.4.15:/export/home/abc/; sleep 10; expect password; send "secretPassword\n";interact'
Run Code Online (Sandbox Code Playgroud)
抛出 - ~/partFiles/*: No such file or directory
只是
scp -C -o CompressionLevel=9 ~/partFiles/* abc@10.200.4.15:/export/home/abc/
然而,完美的作品。
为什么?如何解决这个问题?
我已经制作了下面的期望脚本,我需要记录该脚本的输出。
SOURCE_FILE=`ls -l *.txt --time-style=+%D | grep ${DT} | grep -v '^d' | awk '{print $NF}' `
if [ -n "${SOURCE_FILE}" ]
then
cp -p ${SOURCE_FILE} ${T_FILES}
/usr/bin/expect<<EOD
set timeout 60
spawn sftp $ES_SFTP_USER@$ES_SFTP_HOST_NAME:$R_LOCATION
expect "*?assword:"
send "$password\r"
expect "sftp>"
send "put /opt/AppServer/ES_TEST/todays_report/*.txt\r"
expect "sftp>"
send "bye\r"
expect EOD
EOD
else
echo "No Files to copy" >> ${LOGFILE}
fi
Run Code Online (Sandbox Code Playgroud)
我需要将 Expect 命令的输出记录在${LOGFILE}. 如何做呢?
我尝试添加以下内容,但不起作用。可以做什么?
/usr/bin/expect<<EOD >> ${LOGFILE} 2>&1
set timeout 60
spawn sftp $ES_SFTP_USER@$ES_SFTP_HOST_NAME:$R_LOCATION
expect "*?assword:"
send "$password\r" …Run Code Online (Sandbox Code Playgroud) 我正在编写一个脚本来scp一些文件,但需要通过用户或另一个脚本作为参数传递文件位置
#!/usr/bin/expect
set FILEPATH1 $1
spawn sh "scp $FILEPATH1 $USER@$HOST:/destination/files"
set pass "pass123"
expect {
password: {send "$pass\r"; exp_continue}
}
Run Code Online (Sandbox Code Playgroud)
在 spawn 和 #!/usr/bin/expect 之前也试过这个
FILEPATH1=$1
Run Code Online (Sandbox Code Playgroud)