在bash脚本中处理sys.excepthook错误

8 投票
3 回答
17580 浏览
提问于 2025-04-17 05:20

我写了一个bash脚本,它正好能完成我想要的功能,但出现了以下错误:

关闭失败,文件对象析构函数中:sys.excepthook丢失了sys.stderr

我对此完全无从下手。以下是我的脚本:

#!/bin/bash

usage () { echo "${0##*/} inputfile outputfile"; exit 1; }

(($#==2)) || usage

INPUTFILE="$1"
OUTPUTFILE="$2"

#  All that is written between between the 'cat' command and 
#+ 'EOF' will be sent to the output file.
cat <<EOF >$OUTPUTFILE
$(date "+Generated on %m/%d/%y at %H:%M:%S")

DATA AUDIT: $1

------------
COLUMN NAMES
------------

$(csvcut -n $INPUTFILE)

---------------------------------------
FIRST TEN ROWS OF FIRST FIVE COLUMNS 
---------------------------------------

$(csvcut -c 1,2,3,4,5 $INPUTFILE | head -n 10)

------------
COLUMN STATS
------------

$(csvcut $INPUTFILE | csvstat )

---END AUDIT
EOF

echo "Audited!"

我对shell脚本还很陌生,对python更是新手。如果有人能帮我,我将非常感激。

3 个回答

1

我猜这个 csvcut 的 Python 脚本其他地方都能正常运行,但在尝试关闭文件和退出时出现了错误。

如果你说这个脚本其他功能都正常,并且假设这个错误信息是 'csvcut' 输出到错误流(stderr),那么把它重定向到 /dev/null 可以作为一个临时解决办法。

cat <<EOF >$OUTPUTFILE 2>/dev/null

当然,你在 heredoc 中的其他错误信息也会被重定向到那里。

2

你需要进行两个步骤:

步骤 1:

在你的 csvcut 脚本中,找到所有调用 sys.stdout.write() 的地方,确保在每次 write() 之后都调用 sys.stdout.flush()

步骤 2:

完成步骤 1 后,你现在应该能够在 Python 脚本中捕获到 IOError。下面是一个处理断开的管道的例子:

try:
    function_with_sys_stdout_write_call()
except IOError as e:
    # one example is broken pipe
    if e.strerror.lower() == 'broken pipe':
        exit(0)
    raise       # other real IOError

希望这对你有帮助!

19

我在使用Python 2.6.2脚本的输出通过管道传给Ubuntu 9.04上的head命令时,遇到了一个错误。为了修复这个问题,我在脚本中添加了try块,来在退出脚本之前关闭stdout(标准输出)和stderr(标准错误输出):

try:
    sys.stdout.close()
except:
    pass
try:
    sys.stderr.close()
except:
    pass

现在我不再看到这个错误了。

撰写回答