【问题标题】:Bad substitution Bash: how to write a heredoc to a dynamically created file (variable)?坏替换 Bash:如何将 heredoc 写入动态创建的文件(变量)?
【发布时间】:2016-04-30 21:56:46
【问题描述】:

我即将在 php 中生成大量调查。

我正在使用 Bash 通过 cat 命令添加某种自动化。所以我使用 Bash 来生成.php 文件。

要添加新调查,我的 Bash 脚本会使用 filecount='ls -l ${survey_dir}${survey_category} | wc -l' 计算调查目录中的文件。我想使用filecount 来生成下一个调查的文件名。所以如果survey_category目录有两个文件,那么新的文件名就是3.php

在启动 heredoc 之前,我发出以下变量和命令:

filecount=$((filecount+1))
newfile="${wd}${catg}/${filecount}.php"
cat > ${newfile} <<-EOF
...
EOF

当我执行脚本时,cat 命令会产生错误消息“替换错误”。

我试图通过引用&lt;&lt;-EOF 来克服这个问题:比如&lt;&lt;-'EOF',但是我在php 中使用了很多变量替换,所以这个解决方案无法实现。

我检查了ls -l /bin/bash 是否实际上链接到bash 而不是dash 或另一个sh shell。

我检查了我的“shebang”是否为#!/bin/bash 而不是#!/bin/sh。检查没问题。

此外,我尝试在变量 ${newfile}: 上使用单引号和双引号:无济于事。

调试信息#!/bin/bash -x:

: bad substitution
+ [[ 1: == \2\: ]]
+ [[ 1: == \3\: ]]
+ [[ 1: == \4\: ]]

我的问题是:如何将 heredoc 写入动态创建的文件?

导致问题的代码:

    echo -e "Your question please:"
    read -e rvraag
    rvraag="${rvraag//\"/\^}"
    salt=`date +"%s"`
    filecount=`ls -l ${wd}${catg} | wc -l`
    filecount=$((filecount+1))
    newfile="${wd}${catg}/${filecount}.php"
    cat > ${newfile} <<-EOF

    <?php
     session_start();
    \$st_code =\$_SESSION['studentnr'];
    \$cursuscode ="${catg}";
    \$rdir="/var/www/qqlq.org/www/gen_enq/";
    require_once \$rdir.'/inc/error_reporting.inc';
    require_once \$rdir.'/src/clsQuestionProgress.class.php';
    \$myQuestionProgress = new clsQuestionProgress();
    \$myQuestionProgress->fCreateQuestionProgress( \$st_code, \$cursuscode );
    require_once \$rdir.'/inc/header.inc';
    require_once \$rdir.'/src/clsWriteProgress.class.php';
    echo "<div class='container'><hr>
    Vraag ${catg} ${filecount}<h4> ${rvraag}</h4><br><br>
    <form name='qradio' action =".\$_SERVER['PHP_SELF']." method= 'POST'>
    <div class='radio'><label><input type='radio' name='${catg}${salt}'

    value='1'>${answ1}<label></div>
        <div class='radio'><label><input type='radio' name='${catg}${salt}' value='2'>${answ2}<label></div>
        <div class='radio'><label><input type='radio' name='${catg}${salt}' value='3'>${answ3}<label></div>
        <div class='radio'><label><input type='radio' name='${catg}${salt}' value='4'>${answ4}<label></div>
       <input type='submit' class='btn btn-warning' name='btnCancel${salt}' value='Go Back'>
       <input type='submit' class='btn btn-success' name='btn${catg}${salt}' value='Ok'>
    </form>
    <hr></div>";
    if (  \$_POST['${catg}${salt}'] == "${answok}" && isset( $_POST['btn${catg}${salt}'] ) ){
          \$myProgress = new clsWriteProgress();
          \$tablename = 'q'.\$st_code.\$cursuscode;
          \$myProgress->fSetProgress( \$tablename, \$_SESSION["leerjaar"],$st_code,\$cursuscode,"${rvraag}",1 );
          \$nextpage=${filecount)+1;
          echo '<script>location.replace("'.\${nextpage}.php.'");</script>';
    }//end if

     if (  \$_POST['${catg}${salt}'] !== "${answok}" && isset( \$_POST['btn${catg}${salt}'] ) ){

          \$tablename = 'q'.\$st_code.\$cursuscode;
          \$myProgress = new clsWriteProgress();
          \$myProgress->fSetProgress( \$tablename, \$_SESSION["leerjaar"],\$st_code,\$cursuscode,"${rvraag}",0 );
          \$nextpage=${filecount)+1;
          echo '<script>location.replace("'.${nextpage}.php.'");</script>';
    }//end if

    if ( isset( \$_POST['btnCancel${salt}'] ) ){
            echo '<script>location.replace("../../studyoverview.php" );</script>';

    }//end if
EOF

【问题讨论】:

  • 这是可疑的 - cat &gt; ${newfile} &lt;&lt;-EOF - 删除破折号
  • @Ed Heal:当我删除破折号时,会出现一条错误消息:warning: here-document at line 57 delimited by end-of-file (wanted EOF')`。我需要破折号来跳过脚本中的标签..
  • 你能发布整个代码吗?删除破折号不应导致此类错误。
  • 代码:wd="/var/www/example.com/www/survey/" filecount='ls -l ${wd}${catg} | wc -l' catg="survey01"; filecount=$((filecount+1)) newfile="${wd}${catg}/${filecount}.php" echo "${newfile}" cat &gt; ${newfile} &lt;&lt;-EOF &lt;?php ..... ?&gt;EOF
  • @nsilent22 如果以EOF 结尾的行以制表符开头。

标签: php bash shell


【解决方案1】:

正如 Benjamin W 的评论中所指出的,问题是在应该写入文件的 php 代码中引起的。

在我写的代码中 $nextpage=${filecount)+1;括号里的符号!

应该是: $nextpage=${filecount}+1;

分析“错误替换”错误的策略是从一个空的 bash 脚本开始。 之后我写了heredoc骨架逐行测试它。 当没有返回错误时,我粘贴以下行,依此类推,直到达到 '$filecount}+1' 表达式。

问题已解决,感谢您的反馈!

【讨论】:

    【解决方案2】:

    如果您在知道已安装 PHP 的环境中工作,只需将其重写为 PHP shell 脚本即可。说真的,有些头痛不值得你花时间。如果您正在寻找快速而肮脏的东西,Bash 是不错的选择,但是一旦您开始将某些字符(主要是美元符号)加入其中,您就会为大量调试做好准备。

    从命令行使用 PHP 的详细信息:
    http://www.php.net/cli

    您可以使用以下命令在命令行获取用户输入:

    echo "Your question please: ";
    $question = fgets(STDIN);
    

    (毫无疑问,有些人会认为 Python 或 Perl 是更好的选择,但既然你输出的是 PHP,那么坚持使用单一语言是有意义的。)

    【讨论】:

      【解决方案3】:

      @kzpm:根据您提供的代码,这对我有用:

      !/bin/bash
      
      wd="/tmp/workdir/"
      catg="survey01"
      mkdir -p ${wd}${catg}
      filecount=`ls ${wd}${catg} | wc -l`
      filecount=$((filecount+1))
      newfile="${wd}${catg}/${filecount}.php"
      echo "${newfile}"
      cat > ${newfile} <<-EOF
      <?php ..... ?>
      EOF
      

      我所做的更改:
      1. ls 的反引号(代码中的单引号,可能就是这种情况)
      2. 在开头移动设置catg值(你是在filecount之后声明的)

      【讨论】:

        【解决方案4】:

        我相信 heredoc 的语法是

        【讨论】:

        • 来自man bash:如果重定向操作符是
        • @Todd:破折号- 用于忽略结果文件中的选项卡。查看我对 Ed Heal 的评论
        猜你喜欢
        • 2011-02-26
        • 2015-09-06
        • 2011-09-06
        • 1970-01-01
        • 2010-11-13
        • 1970-01-01
        • 2019-08-05
        • 2022-12-18
        相关资源
        最近更新 更多