【问题标题】:Force Bash-Script to wait for a Perl-Script that awaits input强制 Bash 脚本等待等待输入的 Perl 脚本
【发布时间】:2018-02-07 17:16:30
【问题描述】:

我有一个 Bash 脚本,它顺序运行一些从文件中读取的 Perl 脚本。这些脚本需要按 Enter 才能继续。

奇怪的是,当我运行脚本时,它从不等待输入,而是继续。我假设 Bash-Script 中的某些内容被解释为 Enter 或其他一些按键,并使 Perl 继续运行。

我确定有解决方案,但我真的不知道要寻找什么。

我的 Bash 有这个循环遍历 Perl 脚本列表(在 seqfile 中列出)

while read zeile; do
    if [[ ${datei:0:1} -ne 'p' ]]; then
        datei=${zeile:8}
    else
        datei=$zeile
    fi
    case ${zeile: -3} in
    ".pl")
    perl  $datei  #Here it just goes on...
    #echo "Test 1"
    #echo "Test 2"
    ;;
    ".pm")
        echo $datei "is a Perl Module" 
    ;;
    *)
        echo "Something elso"
    ;;
    esac
done <<< $seqfile;

您注意到带有echo "Test 1/2" 的两条注释行。我想知道它们是如何显示的。 实际上它们是写在彼此下面的,就像有一个 Enter-Press:

Test 1
Test 2

Perl 脚本的输出是正确的,我只需要弄清楚如何强制从用户而不是脚本读取输入。

【问题讨论】:

  • 在命令行上执行 perl 脚本会发生什么。它会立即返回提示吗?
  • 打印 $datei 的值以确保是你想要的。
  • @LuisMuñoz - 如果脚本在命令行上执行,它会按预期工作(在使用相同的命令多次执行各种 Perl 脚本后,我决定进行一些自动化操作)。实际上,Bash 脚本有效 - 它只是跳过我想要提供的输入。

标签: bash perl user-input


【解决方案1】:

让 perl 脚本重定向来自 /dev/tty 的输入。

概念证明:

while read line ; do
    export line
    perl -e 'print "Enter $ENV{line}: ";$y=<STDIN>;print "$ENV{line} is $y\n"' </dev/tty
done <<EOF
foo
bar
EOF

程序输出(用户输入粗体):

Enter foo: 123 foo is 123
Enter bar: 456 bar is 456

【讨论】:

  • 我不得不重新写了一点,但基本上只是将一行改为perl $zeile &lt;/dev/tty。我不希望它等待每一个输​​入(有时根本不需要输入)。我看到您对 bash 的了解比我的多,您是否介意解释一下为什么使用 -e 参数并在之前导出该行而不是直接使用它? (已投票并标记为答案,但一些解释会很好,谢谢)
  • -eexport 可能与您的具体问题无关。 -e 指示 perl 将下一个命令行参数视为要执行的 perl 代码,而不是包含 Perl 代码的文件。 export 使 bash 变量 $line 在 Perl 进程中可用,因此我可以输出它。
【解决方案2】:

@mob 的回答很有趣,但我想为您的用例提出一个替代解决方案,如果您的整个 bash 脚本以特定的输入重定向运行(即不是 @ 987654323@).

最小的工作示例:

  • script.perl

    #!/usr/bin/env perl
    use strict;
    use warnings;
    {
        local( $| ) = ( 1 );
        print "Press ENTER to continue: ";
        my $resp = <STDIN>;
    }
    print "OK\n";
    
  • 脚本.bash

    #!/bin/bash
    
    exec 3>&0 # backup STDIN to fd 3
    
    while read line; do
        echo "$line"
        perl "script.perl" <&3 # redirect fd 3 to perl's input
    done <<EOF
    First
    Second
    EOF
    
    exec 3>&- # close fd 3
    

所以这将适用于:./script.bash 在终端和yes | ./script.bash 例如...

有关重定向的更多信息,请参阅例如this articlethis cheat sheet

希望对你有帮助

【讨论】:

  • 恐怕你迟到了 8 秒,但我觉得你的回答很有趣,你的链接很有帮助(点赞!),但我无法让你的解决方案发挥作用:/ bash: [[: /: syntax error: operand expected (error token is "/") bash: 3: Bad file descriptor跨度>
  • @Qohelet 我无法重现您的错误。您是否按原样复制了 script.bash 文件并运行 chmod a+x script.bash &amp;&amp; ./script.bash ?如果是,您能否提供有关您的配置(例如操作系统和外壳)的更多提示?如果您在终端中运行exec 3&gt;&amp;0,是否也会出现同样的错误?
  • 您可能还想在终端中运行ls -l /dev/fd/ 以获取打开的文件描述符列表
  • 忽略了您的 exec 3&gt;&amp;0 并没有将其放入我的代码中:/ - 您的想法非常有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多