#python #bash #shell #unix
#python #bash #оболочка #unix
Вопрос:
Я написал скрипт bash, который делает именно то, что я хочу, но выдает следующую ошибку:
close failed in file object destructor: sys.excepthook is missing lost 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!"
Я довольно новичок в сценариях оболочки и очень новичок в python. Я был бы благодарен за любую помощь.
Комментарии:
1. Ошибка возникает из скрипта python (csvcut?), А не из вашего скрипта bash. Было бы более полезно вместо этого просмотреть соответствующий код: D
2. Может быть, csvcut не нравится заголовок, поскольку он заставляет стандартный вывод процесса преждевременно закрываться?
3. @Antti, я предполагал, что это так, но мне интересно, могу ли я что-то сделать в скрипте, чтобы решить проблему, поскольку выполнение команд по отдельности в командной строке не приводит к возникновению ошибки. Есть ли у вас представление о том, как можно изменить заголовок для решения возможной проблемы стандартного вывода? Или для этого все еще будет необходим код csvcut? И спасибо!
4. почему вы работаете с заменами команд, т. Е.
$(csvcut $INPUTFILE | csvstat )
Когда Все, что вам нужноcsvcut $INPUTFILE | csvstat
. Удачи.5. Потому что это heredoc, нет? То, что вы предлагаете, не работает. Я неправильно понимаю? Надеюсь, вы продолжите, и спасибо, что вмешались.
Ответ №1:
Я видел эту ошибку при передаче выходных данных из скрипта Python 2.6.2 в head
команду в bash
Ubuntu 9.04. Я добавил try
блоки для закрытия stdout
и stderr
перед выходом из скрипта:
try:
sys.stdout.close()
except:
pass
try:
sys.stderr.close()
except:
pass
Я больше не вижу ошибки.
Комментарии:
1. Любое объяснение того, почему это работает? Я получаю эту ошибку в скрипте cython, который выполняет некоторое перенаправление с помощью dup / dup2, и это, кажется, все исправляет.
2. Решение также работает с вызовами
.flush
вместо.close
. Я не знаю, означает ли это что-нибудь. (close
подразумеваетflush
). Python 2.7.8 на Ubuntu 14.043.
-u
Опция python (небуферизованный вывод) также кажется актуальной. Когда-u
передается, я не могу воспроизвести проблему
Ответ №2:
Вам нужно выполнить два шага:
Шаг 1:
В вашем скрипте csvcut найдите все места, где sys.stdout.write()
вызываются, убедитесь sys.stdout.flush()
, что вызывается после каждого write()
.
Шаг 2:
После завершения шага 1 вы теперь сможете выполнять захват IOError
в скрипте Python. Ниже приведен один пример того, как обрабатывать поврежденный канал:
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
Надеюсь, это поможет!
Комментарии:
1. В моем случае это было правильное исправление. Похоже, что трассировка все еще записывалась в stderr во время завершения работы скрипта, и сброс stderr перед завершением работы сделал свое дело.
Ответ №3:
Я предполагаю, что скрипт csvcut
Python в остальном функционален, но выдает ошибку при попытке закрыть файлы и выйти.
Если, как вы говорите, скрипт работает в противном случае и предполагает, что ошибка ‘csvcut’ выдает выходные данные в stderr, то перенаправление ее в /dev/null будет временным исправлением.
cat <<EOF >$OUTPUTFILE 2>/dev/null
Естественно, любые другие сообщения об ошибках в вашем heredoc также будут перенаправляться туда.
Комментарии:
1. Даже в качестве временного исправления это не работает для меня. Все еще получаю ту же ошибку.