Bash - Como tornar os comandos em execução mais interativos?

1

Constantemente descubro que executo comandos bash e continuo editando o comando (usando o modo vi) para acertar.

Isso muitas vezes me envolve voltando ao comando, pulando para lugares no meio do comando e mudando as coisas. Eu posso fazer isso bem rápido no modo vi, mas ainda acho lento e propenso a erros.

Às vezes, salvo comandos como esse em um arquivo, edito o arquivo e o executo novamente, etc., mas isso me fez pensar ...

Existe uma maneira mais interativa de iterar em um comando bash? Mais como um REPL de alguma forma que é mais fácil editar as entradas para comandos?

Por exemplo, digamos que estou repetindo o seguinte comando. O que é uma maneira fácil de atualizar "test", "super" e "java $" sem voltar através do comando usando o modo vi ou editá-lo em um script?

$ find . | grep test | grep super | grep java$

Outro exemplo pode ser a execução de um curl em um servidor remoto e a substituição de argumentos diferentes. Às vezes, eu definia variáveis e as passava para a onda, assim:

$ curl "http://example.com/$PATH/$PARMS"

mas acho que isso é muito pesquisando meu histórico de comandos para definir variáveis, etc., pois isso fica mais complexo.

    
por Brad Parks 16.03.2018 / 13:15

1 resposta

0

Tenho certeza de que isso pode ser melhorado, mas eu apenas juntei isso para permitir prompts no meio de comandos usando subshells. Assim, no exemplo simples a seguir, ele me perguntaria interativamente por dois parâmetros toda vez que eu executá-lo e, em seguida, produziria esse resultado.

$ echo "hi $(ask name), how $(ask old) are you?"
:name (This is a prompt. I supplied "brad" as the value)
:old  (This is another prompt. I supplied "young" as the value)

hi brad, how young are you?

Se eu executar uma segunda vez, lembrei-me do que dei a ela para entradas (salva-as em um arquivo temporário em /tmp ). Isso pode ser desabilitado passando "não" como segundo parâmetro.

$ echo "hi $(ask name), how $(ask old) are you?"
:brad (This is a prompt. I supplied "parks" as the value)
:young  (This is another prompt. I hit enter to use the default value)

hi parks, how young are you?

Nota:

  • Todos os arquivos tmp podem ser removidos executando ask clear
  • A ajuda pode ser exibida executando ask help
  • Isso requer o bash 4.x, já que read -i não está disponível nos bashs mais antigos. Isso é para fornecer o pedido com um valor padrão. Você pode atualizar o bash usando homebrew.

Aqui está o roteiro!

pergunte

#!/usr/local/bin/bash
me=$(basename "$0")

show_help()
{
it=$(cat <<EOF
  Prompts you for info, allowing a default value that can also
  be updated by being stored in a tmp file.

  Useful for interactively replacing parts of a bash command 
  you're running with a new value easily, instead of having 
  to manually edit the command all the time.

  usage: $me {default_value} {tmp_key} 

  e.g. 

    $me        -> asks for input

    $me HI     -> asks for input, with "HI" supplied as default value. 
                  Saves the user supplied value in a tmp file, and 
                  uses that as the default the next time it's run

    $me 1 no   -> asks for input, with 1 supplied as default value. 
                  If tmp_key is any value other than "no", will 
                  save the user supplied value in a tmp file, and 
                  use that as the default the next time it's run

    $me clear  -> removes any tmp files that have been created.

  A more real example, the following will curl an url at
  a site, and constantly ask you for the page you want to hit,
  remembering the last value you used in a tmp file.

  $ curl http://httpbin.org/\$($me somePage)
EOF
)
  echo "$it"
  exit
}

# Store tmp files in a folder
tmp_file_path="/tmp/__${me}"
mkdir -p "$tmp_file_path"

prompt=":"

if [ "$1" = "help" ]
then
  show_help
fi
if [ "$1" = "clear" ]
then
  rm -fr "$tmp_file_path"
  echo "Removed any tmp files from $tmp_file_path"
  exit;
fi

# Initialize our default value and tmp file name
default_value=${1:-""}
tmp_key_default=$(echo "$default_value" | head -n1 | tr -cd '[[:alnum:]]._-')
tmp_key=${2:-"no"}
if [ -n "$1" ]
then
  if [ -z "$2" ]
  then
    tmp_key=$tmp_key_default
  fi
fi

# Convert tmp_key to lower case
tmp_key=$(echo "$tmp_key" | tr '[:upper:]' '[:lower:]')

# Get the default value to prompt with
tmp_file="$tmp_file_path/$tmp_key"
if [ "$tmp_key" != "no" ]
then
  if [ -f "$tmp_file" ]; then
    default_value=$(cat "$tmp_file")
  fi
fi

# Ask the user for input, supplying the default
read -r -e -p "$prompt" -i "$default_value" result
echo "$result"

# Save the new value to a tmp file if we're supposed to
if [ "$tmp_key" != "no" ]
then
  echo "$result" > "$tmp_file"
fi
    
por 16.03.2018 / 13:15

Tags