¿Cómo pruebo una cadena vacía en una sentencia Bash case?


Tengo un script Bash que realiza acciones basadas en el valor de una variable. La sintaxis general de la sentencia case es:

case ${command} in
   start)  do_start ;;
   stop)   do_stop ;;
   config) do_config ;;
   *)      do_help ;;
esac

Me gustaría ejecutar una rutina predeterminada si no se proporciona ningún comando, y do_help si el comando no está reconocido. Intenté omitir el valor del caso así:

case ${command} in
   )       do_default ;;
   ...
   *)      do_help ;;
esac

El resultado era predecible, supongo:

syntax error near unexpected token `)'

Luego intenté usar mi mejor oportunidad en una expresión regular:

case ${command} in
   ^$)     do_default ;;
   ...
   *)      do_help ;;
esac

Con esto, un empty{comando} vacío cae a través de la * caso.

Estoy tratando de hacer lo imposible?

Author: Singlestone, 2013-07-10

4 answers

La instrucción case usa globs, no regexes, e insiste en coincidencias exactas.

Así que la cadena vacía se escribe, como de costumbre, como "" o '':

case "$command" in
  "")        do_empty ;;
  something) do_something ;;
  prefix*)   do_prefix ;;
  *)         do_other ;;
esac
 90
Author: rici,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-10 16:10:33

Aquí hay una solución:

case _${command} in
   _start)  do_start ;;
   _stop)   do_stop ;;
   _config) do_config ;;
   _)       do_default ;;
   *)       do_help ;;
esac

Obviamente puedes usar el prefijo que quieras.

 6
Author: Zero Piraeus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-10 16:06:41

Utilizo una simple caída. ningún parámetro pasado ($1="") será capturado por la segunda instrucción case, sin embargo el siguiente * capturará cualquier parámetro desconocido. Voltear el"") y*) no funcionará como*) atrapará todo cada vez en ese caso, incluso espacios en blanco.

#!/usr/local/bin/bash
# testcase.sh
case "$1" in
  abc)
    echo "this $1 word was seen."
    ;;
  "") 
    echo "no $1 word at all was seen."
    ;;
  *)
    echo "any $1 word was seen."
    ;;
esac
 2
Author: Ernie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-05 00:22:01

Así es como lo hago (a cada uno lo suyo):

#!/bin/sh

echo -en "Enter string: "
read string
> finder.txt
echo "--" >> finder.txt

for file in `find . -name '*cgi'`

do

x=`grep -i -e "$string" $file`

case $x in
"" )
     echo "Skipping $file";
;;
*)
     echo "$file: " >> finder.txt
     echo "$x" >> finder.txt
     echo "--" >> finder.txt
;;
esac

done

more finder.txt

Si estoy buscando una subrutina que existe en uno o dos archivos en un sistema de archivos que contiene docenas de archivos cgi, introduzco el término de búsqueda, por ejemplo, 'ssn_format'. bash me devuelve los resultados en un archivo de texto (finder.txt) que se ve así:

-- ./ registry / master_person_index.cgi: SQLClinic::Seguridad::ssn_format($usuario,$script_name,$local,$Local,$ssn) si $ssn ne "";

 1
Author: Thomas Altfather Good,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-23 16:03:23