【问题标题】:Getting list of files using expect command in a shell script在 shell 脚本中使用 expect 命令获取文件列表
【发布时间】:2021-02-18 19:23:02
【问题描述】:

如何在 shell 脚本中使用 expect 命令获取文件列表

我的脚本外壳:

remotepass="12345"

echo
echo "list files ssh"
echo "=========="
listDoc=$(ssh user@111.111.111.111 ls /data/dcrm_int/ftp/out/rpt/dwh/20200820/*DWH_CRM_SYS_OPERLOG_20200820*)
echo $listDoc

echo
echo "list files"
echo "=========="
for document in $listDoc; do
    echo $document
done

cat > expect_1.dat << EOF
    spawn ssh user@111.111.111.111 ls /data/dcrm_int/ftp/out/rpt/dwh/20200820/*DWH_CRM_SYS_OPERLOG_20200820*
    expect "*?assword*"
    send "$remotepass\r"
    interact
EOF
listDoc=$(expect "expect_1.dat")

echo
echo "result"
echo "======"
echo $listDoc

echo
echo "list files"
echo "=========="
for document in $listDoc; do
    echo $document
done

我希望得到的结果就像第一个红框一样

有没有办法只显示文件和目录

【问题讨论】:

  • WT...?对我来说不清楚。 1 请勿发布文字图片。您的结果应该是问题内的剪切粘贴文本,而不是图像。 2 您的脚本在第一部分执行 ssh 并获得正确的结果。那为什么要使用expect呢? 3 如果你想使用 SSH 无密码登录,设置密钥,不要设置期望。 4 我不确定这里的问题是什么......
  • 在第一部分,我得到了正确的结果,但我必须输入密码。在那台PC上,我无法配置密码,我必须使用expect命令。 expect 命令返回我需要的信息,但它在最后,我不知道如何过滤以仅获取文件的路径。
  • 如您所见,红框不会给您带来任何朋友 ;-) ... 使用鼠标选择文本的编辑菜单中的{} 工具将格式设置为code/data/requiredOutput/ExactErrMsgs . 2) 可能在ssh expect 命令的末尾添加2&gt;/dev/null 将隐藏不需要的横幅数据。否则,由于它是标准消息(诚然可以更改),您可以添加 grep -Ev '^spawn|^Authorized|^Password' 以在不需要的消息进入您的循环之前将其删除。好的第一个问题(屏幕截图除外)。继续发帖,祝你好运。
  • Expect 使用可以处理字符串的 Tcl 语言。如果你对shell语言比较熟悉,可以看看我的sexpect
  • 你也可以将输出重定向到一个文件并用shell脚本解析它。

标签: bash shell ssh expect


【解决方案1】:

默认情况下,spawn 会回显所有发送的内容以及接收的内容。 您可以通过添加到期望脚本开始来禁用它:

log_user 0

这将删除不需要的起始文本。

一个看不见的问题是输出在每行的末尾包含回车符control-M。您可以通过这样做来验证这一点

echo "$listDoc"|cat -v

每行将在哪里结束^M。这是因为 spawn 使用的 pty 将继承包括 onlcr 的当前 stty 设置,即将输出换行符转换为回车换行符。您可以通过多种方式删除这些字符,但也可以通过添加到期望脚本开始来避免它们:

set stty_init -onlcr

另一个问题是输出以空行开头。您可以通过添加来避免这种情况

expect "\n"

就在interact之前。

确保在 shell 中用双引号括起变量:

echo "$listDoc"

【讨论】:

  • 还有spawn -noecho
  • stty_init 的绝妙技巧,我以前没见过。
【解决方案2】:

请接受@meuh's answer

一个shell提示,使用,将输出的读入一个数组:

mapfile -t listDoc < <(expect "expect_1.dat")

然后

echo
echo "list files"
echo "=========="
for document in "${listDoc[@]}"; do
    echo "$document"
done

阅读Security implications of forgetting to quote a variable in bash/POSIX shells


列出meuh的建议:

cat > expect_1.dat << EOF
    log_user 0
    set stty_init -onlcr
    spawn ssh user@111.111.111.111 ls /data/dcrm_int/ftp/out/rpt/dwh/20200820/*DWH_CRM_SYS_OPERLOG_20200820*
    expect "*?assword*"
    send "$remotepass\r"
    log_user 1
    expect eof
EOF

引用heredoc 通常是个好主意,特别是如果您要在expect 中编写更多代码并使用expect 变量。然后,您可以通过环境将shell变量传递给期望:

export remotepass
# note the quotes in the next line: the whole heredoc is a single quoted string
cat > expect_1.dat << 'EOF'
    log_user 0
    set stty_init -onlcr
    spawn ssh user@111.111.111.111 ls /data/dcrm_int/ftp/out/rpt/dwh/20200820/*DWH_CRM_SYS_OPERLOG_20200820*
    expect "*?assword*"
    send "$env(remotepass)\r"   # using the environment variable
    log_user 1
    expect eof
EOF

【讨论】:

    猜你喜欢
    • 2014-11-03
    • 1970-01-01
    • 2014-05-04
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多