2010-08-13 6 views

Respuesta

15

Los scripts de shell se analizan línea por línea a medida que se ejecutan, por lo que solo debe asegurarse de que la ejecución nunca llegue a los datos que desea proteger. Usted puede hacer esto, por ejemplo:

# Some shell code... 

exit 

[data (possibly binary) goes here] 

Para realmente leer estos datos de la secuencia de comandos, puede utilizar un poco de magia sed para extraer todo después de la primera línea que contiene sólo __DATA__, a continuación, almacenar el resultado de que el SED en una variable. He aquí un ejemplo:

#!/bin/sh 

data=$(sed '0,/^__DATA__$/d' "$0") 
printf '%s\n' "$data" 

exit 

__DATA__ 
FOO BAR BAZ 
LLAMA DUCK COW 

Si guarda este script como test-data.sh y que sea ejecutable, se puede ejecutar y obtener el siguiente resultado:

$ ./test-data.sh 
FOO BAR BAZ 
LLAMA DUCK COW 
+0

esto es genial, ¿alguien puede explicar cómo funciona esto? No entendí 'data = $ (sed '0,/^ __ DATA__ $/d'" $ 0 ")' – rodee

+0

Ejecuta el comando 'sed' y de la línea 0 a la línea que coincide con __DATA__, elimina la línea. El resto se imprimirá. $ 0 es este script, el archivo para leer que contiene los datos. – mpersico

+0

Cuidado, sin embargo; si está comprando en su script, no solo ejecutándolo, entonces '$ 0' es su nombre de shell y su' exit' saldrá de su sesión completa. Reemplaza '$ 0' con' $ {BASH_ARGV [0]} 'y' exit' con 'return'. – mpersico

3

En primer lugar las de Perl "__DATA__" Pragma es una forma de proporcionar entrada a $ _ sin especificar un archivo. No hay equivalente en bash ya que no tiene nada similar a $ _. Sin embargo, puede suministrar datos directamente en un script bash por otros medios, como variables de configuración explícitas, utilizando documentos HERE, etc.

Sin embargo, no estoy seguro de que esto sea lo que desea hacer. Parece que después de algún tipo de método de comentarios en bloque. Es ese el caso?

+0

Sí, pero la otra parte también es interesante. Así que aceptaré la solución de salida aunque no es tan buena como __DATA__ porque después de __DATA__ no hay más resaltado de sintaxis y __DATA__ en sí mismo es más visible en el código que la salida. Para el suministro de datos, probablemente nos haríamos AQUÍ documento, ya que es más fácil de recordar que la propuesta de bcat. –

+1

Sí, utilizar un heredoc es casi seguro la mejor solución para suministrar grandes cantidades de datos a un script. La única vez que utilizaría mi solución (que no sea como una prueba de concepto) es si necesitaba la capacidad de incluir datos fácilmente en un script de shell que posiblemente podría incluir el terminador heredoc. – bcat

+0

IIUC, el establecimiento explícito de variables y el uso de heredocs tendrá el efecto de tener sus datos justo en el medio de su código. La técnica __DATA__ pondrá todos esos datos al final para que pueda leer el código sin la interrupción del contexto. IMO, usar esto para datos NO es óptimo. Es mejor leer desde una fuente externa. PERO, podría ser apropiado para una prueba de auto-documentación. Solo lo uso para las declaraciones de USO como arriba. – mpersico

0

Esta es una técnica útil si desea proporcionar información de uso para su secuencia de comandos, pero no desea saturar la línea principal de código con el texto de ayuda. También es excelente si desea hacer referencia al uso más de una vez. A saber, un fragmento de un script mío:

... 
declare OPTSARGS  
OPTSARGS=$(getoptp -o wh --long nopager,help -n myScript-- "[email protected]") 
status=$? 
if ((status != 0))  
then 
    printf '%s\n' "$(sed '0,/^__USAGE__$/d' $0)" 
    exit $status 
fi 
eval set -- "$OPTSARGS" 
while true 
do 
    case "$1" in 
     -w) diffargs="$diffargs -w"; shift;; 
     --nopager) pager=cat; shift;; 
     --) shift; break ;; ## end of opts, remaining $*, if any, are args 
     -h | --help) 
      printf '%s\n' "$(sed '0,/^__USAGE__$/d' $0)" 
      exit 0;; 
     *) 
      echo "Internal error!" 
      printf '%s\n' "$(sed '0,/^__USAGE__$/d' $0)" 
      exit 1;; 
    esac 
done 

... 

echo "Done" 
exit 0 

__USAGE__ 
myScript [-w] [--nopager] [file [file...] ] 

Some description goes here. 

     -w - Do not compare whitespace 
--nopager - Do not pass the output through 'less' 
Cuestiones relacionadas