输出显示得太早

时间:2016-08-11 18:25:28

标签: bash printf echo

我制作了一个小的Bash脚本,让我的生活更轻松。但是我遇到了一个我无法解决的问题。

我想要什么
我做了一个小脚本,每次保存/更改文件时都会检查文件中的php错误。这是在没有我每次都需要运行命令的情况下完成的。所以我在第二个屏幕上运行一次Bash脚本,而不是每次在屏幕上保存我的PHP文件时;我自动在屏幕2上显示最终错误。

基本算法

  1. 获取文件的哈希值
  2. 将其与之前的哈希值
  3. 进行比较
  4. 如果不同,则更改/保存文件:使用php -l命令检查是否有错误
  5. 打印php -l
  6. 的结果

    问题: php -l的结果会在我的代码要求之前打印出来。

    代码

    #!/bin/bash
    
    #Declaring basic variables here
    fileToCheck="$1"
    
    oldHash=("")
    checksum=("")
    
    #Function to get a striped line as long as the terminal width
    function lineAmount {
        cwidth=`tput cols`
        lines=""
        for i in $(seq $(expr $cwidth - 33)); do lines="$lines-";done
        echo $lines
    }
    
    
    #Function to show the actual error
    function showError {
        msg=$1
        time=`date +"%c"`
        l=$(lineAmount)
    
        if [ "$msg" == "No" ]
            then
                msg="No errors detected."
        fi
    
        printf "\n\n$time $l \n$msg\n"
    }
    
    #Start-screen------------------------------------------------
    printf "Starting session for $1 at $time \n$(lineAmount)\n"
    if [ ! -f $1 ]
        then
            echo "[Error] File $1 not found."
            exit
    fi
    printf "\n\n\n"
    #------------------------------------------
    
    #Printing out error when file changed
    while true
        do
            sleep 0.6 
            checksum=($(sha256sum $fileToCheck))
            checksum=${checksum[0]}
    
            if [ "$checksum" != "$oldHash" ]
                then
                    error=$(php -l $fileToCheck)
                    oldHash=$checksum
    
                    showError $error
            fi
    done
    

    测试文件(test.php):

    <?php
        function foo() {
    
        }
    ?>
    

    脚本输出:

    Starting session for /home/name/Desktop/test.php at  
    -----------------------------------------------
    
    
    
    
    
    Thu 11 Aug 2016 08:16:15 PM CEST ----------------------------------------------- 
    No errors detected.
    

    现在,在 test.php 中删除第4行:

    <?php
        function foo() {
    
    
    ?>
    

    这当然会出错,我的脚本会显示错误:

    Starting session for /home/name/Desktop/test.php at  
    -----------------------------------------------
    
    
    
    
    
    Thu 11 Aug 2016 08:16:15 PM CEST ----------------------------------------------- 
    No errors detected.
    PHP Parse error:  syntax error, unexpected end of file in /home/name/Desktop/test.php on line 6
    
    
    Thu 11 Aug 2016 08:19:37 PM CEST ---------------------------------------------------------------------------------- 
    Parse
    

    但是你可以看到,这不是一个很好的输出。 PHP Parse error: syntax error, unexpected end of file in /home/name/Desktop/test.php on line 6应打印在第二条虚线下方。不低于&#34;未发现错误。&#34; (第一个输出)。

    预期输出:

    Starting session for /home/name/Desktop/test.php at  
    -----------------------------------------------
    
    
    
    
    
    Thu 11 Aug 2016 08:16:15 PM CEST ----------------------------------------------- 
    No errors detected.
    
    
    Thu 11 Aug 2016 08:19:37 PM CEST ---------------------------------------------------------------------------------- 
    PHP Parse error:  syntax error, unexpected end of file in /home/name/Desktop/test.php on line 6
    

    我尝试了很多,我试着改变我的算法,搜索了很多;但它无法正常工作。 我想这个问题就在51号线或29号的某个地方。但我真的看不出有什么问题。

    谢谢!

1 个答案:

答案 0 :(得分:4)

以下是问题的简化版本:

  

为什么会立即打印错误消息而不是将其分配给变量?

$ error=$(php -l test.php)
PHP Parse error:  syntax error, unexpected end of file in test.php on line 5

php -l将错误消息输出到stderr,就像一个好的Unix公民应该这样。 $(..)仅捕获标准输出。

如果要一起捕获stdout和stderr,可以使用:

error=$(php -l $fileToCheck 2>&1)

您还应引用变量,以便将消息作为单个参数传递,因为您目前正在丢弃大部分消息(shellcheck很有帮助):

showError "$error"

作为一个好公民,php也会返回一个有用的退出代码,因此您可以直接检查状态,而不是尝试匹配“否”以查看它是否成功:

if error=$(php -l $fileToCheck 2>&1)
then
  echo "No problems"
else
  echo "It failed with these messages: $error"
fi