tutorial - shell script linux español
KornShell: establece el indicador "-x"(depuración) globalmente? (5)
¿Hay alguna manera de establecer el modo de depuración ( set -x ) en un script KornShell (ksh) globalmente? Actualmente parece que he hecho algo como lo siguiente:
a(){
set -x
#commands
}
b(){
set -x
#more commands
}
set-x
a
#commands
b
Realmente me gustaría tener que llamar al comando set-x en un solo lugar.
Nota: Todo esto está en KSH88 en AIX.
Ejemplo:
#!/bin/ksh
set -x
a(){
echo "This is A!"
}
b(){
echo "This is B!"
}
a
echo "Outside"
b
dev2:/home/me-> ./testSetX + a This is A! + echo Outside Outside + b This is B! dev2:/home/me->
Añádelo a tu línea shebang:
#!/bin/ksh -x
O configúralo en la parte superior de tu script:
#!/bin/ksh
set -x
O inicie su script desde la línea de comando:
ksh -x script_name
Esto es ksh88 en una máquina HP-UX:
me@host ..dev/
$ cat ./test/verbose
#!/bin/ksh
set -x
hello() {
print $1
}
hello kapow!
exit
[email protected]/
$ ./test/verbose
+ hello kapow!
+ print kapow!
kapow!
+ exit
Seguro que parece que funciona bien. Validé que también funciona con un "set -x" en cualquier lugar antes de la primera llamada de función.
Me mudé a un sistema AIX y experimenté el problema que describió. Cuando las funciones se definen como cualquiera de las function a {
o a() {
en AIX ksh88, el set -x
no parece llevarse al alcance de la función local. Cambiando a ksh93 en la misma caja de AIX, las funciones declaradas usando la nueva function a {
sintaxis tampoco llevan el set -x
externo set -x
dentro del alcance interno. Sin embargo, ksh93 se comporta como POSIX sh (y ksh88 en otras plataformas) solía comportarse, llevando el set -x
a la función cuando la función se define en el antiguo método a a(){
. Esto es probablemente debido a la compatibilidad hacia atrás en ksh93, donde intenta emular el comportamiento anterior cuando las funciones se definen de la manera antigua.
Por lo tanto, es posible que pueda cambiar temporalmente el intérprete a ksh93 para fines de depuración, y luego volver a ksh88 si no le gusta tener las matrices más largas, las matrices asociativas, las matemáticas de coma flotante, el espacio de nombres compatible y la mejora arrolladora de 10x en velocidad de ejecución que trae ksh93. ;) Porque parece que la respuesta es "no, no puedes hacer eso" con ksh88 en AIX. :(
Tenga en cuenta que el alcance se ve afectado entre los dos tipos de declaraciones de función
un() { }
vs.
funcionar a {}
En particular, el typset en ksh no funciona como cabría esperar en el primer caso. Descubierto al intentar depurar un script con una función recursiva. Más aquí:
El comportamiento de "set -x" es una "peculiaridad" del shell de AIX (por no decir brain d ...).
Pidió "una forma de establecer el modo de depuración ... globalmente". Esto es lo que hago para lograr esto:
set_x="${set_x-:}"; # Defaults to ":" (NOOP) unless already non-empty
# Using ":" instead of "" makes termination via semicolon work,
# which in turn allows inlining, especially when using SSH.
# Alternatively, if tracing should be on by default:
#set_x="${set_x-set -x}"; # Defaults to "set -x" unless already non-empty
$set_x; # Apply to file scope
f() {
$set_x; # Apply to local scope
echo working...;
}
main() {
$set_x; # Apply to local scope
f;
ssh localhost $set_x/; hostname; # Apply to remote shell scope
ssh localhost "set_x=/"$set_x/" foo"; # Apply to foo called in remote shell
}
main;
Para habilitar el seguimiento, configure $set_x
en el entorno de su script para " set -x
". Para controlar esto en una llamada por llamada, prefija la llamada con " set_x=''set -x''
". Debido a que se utiliza una variable de entorno, este método funciona naturalmente con llamadas anidadas.
Todos esos usos de " $set_x;
" son un poco feos, pero funcionan con todos los shells, y el beneficio generalmente supera el costo.
Otro ejemplo de una "peculiaridad" de shell de AIX:
set -e;
trap "echo trapped at file scope" EXIT;
f() { return 1; }
main() { f; }
main;
Lo anterior debe imprimir "atrapado en el alcance del archivo", pero no imprime nada.
Probé un set -x
global set -x
con ksh88 (en Solaris 10) y ksh93 (Fedora 17) y con ambos comandos, un set -x
global set -x
en la parte superior del script, no tiene el alcance local de la función (es decir, no tiene ningún local efectos).
Como solución, puede habilitar el seguimiento de comandos locales para todas las funciones en el alcance (una vez definidas) y antes de que se typeset
mediante el tipo de typeset
:
$ cat test.ksh
PS4=''$LINENO: ''
set -x
function foo {
print Hello
}
bar() {
print World
}
typeset -ft `typeset +f`
foo
bar
Salida bajo ksh88 (Solaris 10):
$ ksh test.ksh
13: typeset +f
13: typeset -ft bar foo
15: foo
1: print Hello
Hello
16: bar
1: print World
World
Typeset comentado
$ ksh test.ksh
15: foo
Hello
16: bar
World
Salida bajo ksh93 (Fedora 17):
$ ksh test.ksh
13: typeset +f
13: typeset -ft ''bar()'' foo
15: foo
6: print Hello
Hello
16: bar
10: print World
World
Typeset comentado
$ ksh test.ksh
15: foo
Hello
16: bar
10: print World
World
Salida bajo bash
typeset
comentada e print
sustituida con eco:
$ bash test.ksh
15: foo
6: echo Hello
Hello
16: bar
10: echo World
World
(bash 4.2.39 (1) en Fedora 17)
Mismo resultado bajo zsh 5.0.2 en Fedora 17.
Conclusión
Cuando se usa Ksh, solo con ksh93 y la sintaxis de la definición de la función fnname()
un set -x
global set -x
también tiene alcance local. La solución basada en typeset -ft
es una forma relativamente ligera de habilitar el seguimiento de comandos para todas las funciones.
En bash (y zsh), un set -x
global set -x
funciona como se espera, es decir, también tiene alcance local para todas las funciones.
Por lo tanto, escribir nuevas secuencias de comandos usando bash en lugar de ksh podría ser la mejor alternativa debido a esto.
Como nota al margen: bash es probablemente incluso más portátil que ksh88, especialmente más portátil que ksh93.