He intentado encontrar una respuesta a esta pregunta, pero no tengo suerte hasta ahora:
Tengo un script que se ejecuta algunos otros scripts, y muchos de esos otros scripts tienen "conjunto -x" en ellos, lo que hace que se imprimen todos los comandos se ejecutan. Me gustaría deshacerse de eso, pero retener la información si alguna de las secuencias de comandos enviar el mensaje de error en stderr.
Así que no puedo escribir simplemente ./script 2>/dev/null
Además, no tengo privilegios para editar los otros scripts, así que no puedo cambiar manualmente la opción set.
Estaba pensando en el registro de todo, desde stderr al archivo separado y filtrado de los comandos de rastreo, pero tal vez hay una manera más sencilla?

./script 2>some_fileRespuestas:
Con
bash4.1 y superior, puedes hacer(también funciona cuando
bashse invoca comosh).Básicamente, le estamos diciendo
basha la salida de laxtracesalida en el descriptor de archivo de 7 en lugar del predeterminado de 2, y la redirección que descriptor de archivo a/dev/null. El número fd es arbitrario. Use un fd superior a 2 que no se use de otra manera en su secuencia de comandos. Si la envoltura que está entrando en este comando esbashoyash, incluso se puede utilizar un número superior a 9 (aunque es posible que encuentre problemas si el descriptor de archivo es usado internamente por la cáscara).Si la envoltura que está llamando que
bashla escritura es dezsh, también se puede hacer:para que la variable se asigne automáticamente el primer fd libre por encima de 9.
Para versiones anteriores de
bash, otra opción, sixtracese activa conset -x(en lugar de#! /bin/bash -xoset -o xtrace) sería redefinirsetcomo una función exportada que no hace nada cuando se pasa-x(aunque eso rompería el script si (o cualquier otrobashscript que invoque) utilizadosetpara establecer los parámetros posicionales).Me gusta:
Otra opción es agregar una trampa DEPURACIÓN en un
$BASH_ENVarchivo que lo haceset +xantes de cada comando.Sin
set -xembargo, eso no funcionará cuando se haga en un sub-shell.Como @ilkkachu Dicho esto, siempre y cuando tenga permiso de escritura en cualquier carpeta del sistema de archivos, por lo menos debe ser capaz de hacer una copia del guión y editarlo.
Si no hay ningún lugar donde pueda escribir una copia del guión, o si no es conveniente hacer y editar una nueva copia cada vez que hay una actualización del guión original, aún puede hacer:
Eso (y el enfoque de copia) puede no funcionar correctamente si el script hace algo elegante
$0o con variables especiales como$BASH_SOURCE(como buscar archivos que estén relacionados con la ubicación del script en sí), por lo que es posible que deba editar un poco más, como reemplazar$0con la ruta del script ...fuente
{BASH_XTRACEFD}>truco también funciona enbash4.1 o posterior.ksh93obashen la que la variable no se pasa en el entorno del comando (compárese<shell> -c 'export fd; printenv fd {fd}> /dev/null'enzsh,bashyksh93). Se podría hacer que funcione enksh93/bashpor hacerlo en dos pasos o posiblemente usandoeval, pero parabash, que tienen efectos secundarios si la opción xtrace estaba en marcha.Ya que son secuencias de comandos, podría hacer copias de ellos, y editar los.
Aparte de eso, filtrar la salida parecería simple, podría establecer explícitamente
PS4algo más inusual que una sola ventaja, para facilitar el filtrado:(por supuesto, eso colapsará stdout y stdin, pero las tuberías solo stderr en Bash se vuelven un poco peludas, así que lo ignoraré)
fuente
PS4="%%%%" bash script.sh 2> >(grep -ve '^%%%%').bashcuenta cuestiones como quegrepse ejecuta de forma asíncrona (bash no está esperando por ella, por lo que puede (ya menudo lo hace) cosas salida después de que el siguiente comando en la secuencia de comandos se inicia).