2010-04-15 14 views
109

necesito leer un valor de la terminal en una escritura del golpe. Me gustaría poder proporcionar un valor predeterminado que el usuario pueda cambiar.leer una variable en bash con un valor predeterminado

# Please enter your name: Ricardo^ 

En este script el símbolo es "Por favor, introduzca su nombre:" el valor por defecto es "Ricardo" y el cursor sería después de que el valor por defecto. ¿Hay alguna manera de hacer esto en un script bash?

Respuesta

142

puede utilizar parameter expansion por ejemplo

read -p "Enter: " name 
name=${name:-Richard} 
echo $name 
+4

Terminé haciendo algo basado en esto. Lectura en una variable variable 'input' y luego usando' name = $ {input: - $ name} '. – rmarimon

+26

Esto realmente no responde la pregunta. El valor predeterminado debe mostrarse en el aviso. –

+0

y lo que 'nombre = $ {! Input: - $ nombre}' do? –

3
name=Ricardo 
echo "Please enter your name: $name \c" 
read newname 
[ -n "$newname" ] && name=$newname 

establecer el valor predeterminado; Imprímelo; lee un nuevo valor; si hay un nuevo valor, úselo en lugar del valor predeterminado. Hay (o hubo) algunas variaciones entre shells y sistemas sobre cómo suprimir una nueva línea al final de un prompt. La notación '\ c' Parece que funciona en MacOS X 10.6.3 con una fiesta 3.x, y funciona en la mayoría de las variantes de Unix derivados de System V, utilizando Bourne o Korn conchas.

También tenga en cuenta que el usuario probablemente no darse cuenta de lo que está pasando detrás de las escenas; sus nuevos datos se ingresarán después de que el nombre ya esté en la pantalla. Tal vez sea mejor que el formato:

echo "Please enter your name ($name): \c" 
+0

'printf' es más portátil que' echo' – ghostdog74

+1

@ ghostdog74: Tal vez sea así; aquellos de nosotros que aprendimos la programación de los proyectiles hace más de 25 años pasamos un tiempo difícil para determinar qué prácticas seguimos siendo relevantes.Cada vez más parece que Bash ha reescrito casi todo. Sé que printf ha estado por un tiempo como un comando; muy rara vez lo uso, aunque (probablemente, ¿nunca?). Me da la impresión de que debería callarme hasta que haya (re) aprendido bash. Es gracioso; el software en el que trabajo tiene scripts de shell que no funcionan bien, pero el problema no son los bash-ismos. Me cansé de arreglar "si (prueba -z" $ xxx "); ... ''y otros C Shellisms. –

33

En Bash 4:

name="Ricardo" 
read -e -i "$name" -p "Please enter your name: " input 
name="${input:-$name}" 

Esto muestra el nombre después de la solicitud de la siguiente manera:

Please enter your name: Ricardo 

con el cursor al final del nombre y le permite al usuario editarlo. La última línea es opcional y fuerza el nombre a ser el original por defecto si el usuario borra la entrada o por defecto (la presentación de un nulo).

+0

No se puede usar bash4 porque no es estándar en las distribuciones de Debian. Necesito algo que funcione sin mucha molestia. – rmarimon

+0

sin necesidad de la última línea de código, simplemente use 'name' en lugar de' input' en el comando 'read'. – RNA

+1

@RNAer: Al usar la variable adicional, el valor de '$ name' se conserva si el usuario elimina el valor propuesto (y, por lo tanto, ingresa una cadena nula). Todo depende de lo que necesites. Lo dije tanto en mi respuesta. Tienes razón, sin embargo, de que podría haber sido más explícito y haber dicho que si no se utilizaba la línea opcional, la variable podría haber sido 'name'. –

110
read -e -p "Enter Your Name:" -i "Ricardo" NAME 

echo $NAME 
+1

¡Gran respuesta! Solo quiero mencionar que estaba teniendo problemas con eso, porque no vi el espacio entre "Ricardo" y NAME, pero una vez que lo descubrí ... * ¡magia *! ¡Gracias! –

+25

desafortunadamente -i no es una opción válida para OSX 10.7 – undefined

+0

@BrianMortenson Puede actualizar bash usando homebrew: http://stackoverflow.com/questions/16416195/how-do-i-upgrade-bash-in-mac-osx -mountain-lion-and-set-it-the-correct-path – antonagestam

10

Código:

IN_PATH_DEFAULT="/tmp/input.txt" 
read -p "Please enter IN_PATH [$IN_PATH_DEFAULT]: " IN_PATH 
IN_PATH="${IN_PATH:-$IN_PATH_DEFAULT}" 

OUT_PATH_DEFAULT="/tmp/output.txt" 
read -p "Please enter OUT_PATH [$OUT_PATH_DEFAULT]: " OUT_PATH 
OUT_PATH="${OUT_PATH:-$OUT_PATH_DEFAULT}" 

echo "Input: $IN_PATH Output: $OUT_PATH" 

de ejecución de la muestra:

Please enter IN_PATH [/tmp/input.txt]: 
Please enter OUT_PATH [/tmp/output.txt]: ~/out.txt 
Input: /tmp/input.txt Output: ~/out.txt 
+0

Me gusta porque sigue la convención que veo en muchos scripts de shell donde el valor predeterminado está entre corchetes antes de los dos puntos. ¡¡¡Gracias!!! – morphatic

-1

El parámetro -e -t y no trabajan juntos. He intentado algunas expresiones y el resultado fue el siguiente fragmento de código:

QMESSAGE="SHOULD I DO YES OR NO" 
YMESSAGE="I DO" 
NMESSAGE="I DO NOT" 
FMESSAGE="PLEASE ENTER Y or N" 
COUNTDOWN=2 
DEFAULTVALUE=n 
#----------------------------------------------------------------# 
function REQUEST() 
{ 
read -n1 -t$COUNTDOWN -p "$QMESSAGE ? Y/N " INPUT 
    INPUT=${INPUT:-$DEFAULTVALUE} 
    if [ "$INPUT" = "y" -o "$INPUT" = "Y" ] ;then 
     echo -e "\n$YMESSAGE\n" 
     #COMMANDEXECUTION 
    elif [ "$INPUT" = "n" -o "$INPUT" = "N" ] ;then 
     echo -e "\n$NMESSAGE\n" 
     #COMMANDEXECUTION 
    else 
     echo -e "\n$FMESSAGE\n" 
    REQUEST 
    fi 
} 
REQUEST 
+0

Su respuesta no tiene mucho que ver con la pregunta, ¿o sí? ... –

+0

es una alternativa para usar el parámetro -e -t. esta línea de código (-e y -i para el valor por defecto): leen -e -p "Ingrese su nombre:" -i "Ricardo" NOMBRE no funciona con un countDownTimer (-t) – speefak

+0

Sí, pero eso es no preguntado en la pregunta, ¿verdad? –

0
#Script for calculating various values in MB 
echo "Please enter some input: " 
read input_variable 
echo $input_variable | awk '{ foo = $1/1024/1024 ; print foo "MB" }' 
+3

por favor agregue una explicación a su respuesta. –

9

me encontré con esta pregunta, en busca de una manera de presentar algo como:

Something interesting happened. Proceed [Y/n/q]: 

Usando los ejemplos anteriores deduje esto: -

echo -n "Something interesting happened. " 
DEFAULT="y" 
read -e -p "Proceed [Y/n/q]:" PROCEED 
# adopt the default, if 'enter' given 
PROCEED="${PROCEED:-${DEFAULT}}" 
# change to lower case to simplify following if 
PROCEED="${PROCEED,,}" 
# condition for specific letter 
if [ "${PROCEED}" == "q" ] ; then 
    echo "Quitting" 
    exit 
# condition for non specific letter (ie anything other than q/y) 
# if you want to have the active 'y' code in the last section 
elif [ "${PROCEED}" != "y" ] ; then 
    echo "Not Proceeding" 
else 
    echo "Proceeding" 
    # do proceeding code in here 
fi 

Espero que ayude a alguien a no tener que pensar en la lógica, si se encuentran con el mismo problema

+0

Muy agradable. Incluso podría mejorarse un poco para repetir la pregunta si alguien ingresa "k" o algo más que las opciones dadas. – erikbwork

+1

Acabo de escribir este comentario después de una picazón rasguñada. Ahora tengo una función de shell, que incluye lo anterior, y tiendo a usar eso. Shell parece no funcionar bien, así que trato de evitarlo. Podría probar el resultado de mi función, y darle una oportunidad más, pero básicamente, estoy escribiendo herramientas de administración donde las cosas podrían salir mal, así que quiero que el administrador pueda detener la secuencia de comandos limpiamente en cualquier momento. – sibaz

6

que he acabo de utilizar este patrón, que yo prefiero:

read name || name='(nobody)' 
Cuestiones relacionadas