Estoy modificando un script para que le solicite al usuario un archivo de un tipo específico. Si el archivo ingresado no coincide con el tipo de archivo específico, entra en un bucle while y se repite hasta que el usuario ingresa el archivo correcto.
En este caso, le pido al usuario un .zip
archivo en:
read -p "Enter zip file: " package1
while [ package1 != *.zip ] ; do
read -p "Please enter file ending in '.zip': " package1
done <<< package1
echo $package1
He tenido errores hasta este momento. Ahora, aparece un cursor en blanco, sin resultados. Ya sea que ingrese *.zip
o no, pasa a la siguiente línea con un cursor en blanco y sin salida.
¿Pensamientos?
EDITAR:
Muy bien, he decidido seguir el select
bucle y es una opción mucho mejor que while
en este caso.
Pero, ¿qué pasaría si ese zip
archivo (o cualquier tipo de archivo solicitado) pudiera estar en cualquier otro directorio? Quiero que dé la opción de cambiar de directorio mientras estoy en el select-loop
Shell.
Lo intenté hasta ahora:
echo Select zip file:
options=(".." *.zip)
select package1 in "${options[@]}" ; do
case $package1 in
1 ) cd ..; echo Select zip file: ;;
# Different Directory ) ;;
* ) break ;;
esac
done
Pero el bucle no volverá a mostrar los elementos del menú después de cambiar de directorio. No estoy seguro de cómo ofrecer al usuario cd
un camino totalmente diferente al ../
que quiere, ni para qué usarlo.
"All other existing \# file items" ) ... ; break;;
dentro decase
Respuesta1
Hazlo lógicamente más fácil examinando solo la extensión final:
while [ "${package1##*.}" != "zip" ]
do
read -e -p "Specify a .zip file: " package1
done
echo $package1
Respuesta2
Se ha publicado una solución más elegante, pero creo que es importante señalar algunos de los errores que provocan que el script original falle y cómo solucionarlos.
Primero, cuando estés probando la variable package1
en tu bucle while, debes colocar el $
delante de ella para poder leer los datos reales almacenados en esa variable.
A continuación, utilícelo [[...]]
en lugar de [...]
en su prueba de bucle while, ya que esto le permite hacer coincidir el patrón usando su comodín *
. Sin embargo, esto solo funciona en bash, no en sh. Por favor miraesteResponda para obtener una explicación detallada del uso de [[...]]
versus [...]
.
Por último, no es necesario pasar la cadena <<< package1
al final del ciclo while.
Aquí hay una versión modificada de su script que funciona según lo previsto.
#!/bin/bash
read -p "Enter zip file: " package1
while [[ "$package1" != *.zip ]]; do
read -p "Please enter file ending in '.zip': " package1
done
echo $package1
Respuesta3
Nunca haga que el usuario escriba las rutas de los archivos de forma interactiva. Es más fácil para ellos llamar a su secuencia de comandos con los nombres de ruta de sus archivos Zip en la línea de comando de la secuencia de comandos. Esto les permite utilizar la función de finalización de nombres de archivos y los patrones globales de nombres de archivos del shell.
El script se llamaría usando, por ejemplo,
./myscript /some/path/myarchive.zip
o
./myscript folder/archive-*.zip
o similar.
En el guión, harías
#!/bin/bash
for archive_path do
printf 'Processing archive "%s"...\n' "$archive_path"
# code to process "$archive_path" goes here
done
El bucle en el script recorrería todos los argumentos pasados al script y, en cada iteración, "$archive_path"
sería el nombre de ruta de un archivo individual pasado al script.
No es necesario verificar si el nombre del "$archive_path"
archivo termina con una cadena en particular, ya que es posible que las herramientas que usaría en el archivo ni siquiera se preocupen por el sufijo del nombre del archivo. Si lo hacen, fallarán con el código de salida apropiado, que usted podría detectar fácilmente:
if ! unzip "$archive_path"; then
printf 'Failed to run unzip on "%s"\n' "$archive_path" >&2
exit 1
fi
Si lo usa set -e
en el script (probablemente como su primera declaración), saldrá automáticamente cuando cualquier comando (que no sea parte de una declaración condicional) regrese con un código de salida distinto de cero.
set -e
# The following would terminate the script if it failed:
unzip "$archive_path"
Con respecto a su "edición" agregada: lo que está haciendo allí es comenzar a implementar una herramienta de exploración de archivos o un administrador de archivos para seleccionar archivos Zip. Dependiendo de para qué desee utilizar este código, esto puede ser excesivo.
Respuesta4
Si desea que el usuario seleccione uno deexistentefiles, lo usaría select
en lugar de read
, para permitir que el usuario seleccione de una lista, en lugar de escribir un nombre de archivo que quizás no sepa exactamente.
select package1 in *.zip; do
break;
done
echo "$package1"
Al usuario se le presentará una lista y escribirá el número.