Bash - 如何使正在运行的命令更具交互性?

Bash - 如何使正在运行的命令更具交互性?

我不断发现我运行 bash 命令,并不断编辑命令(使用 vi 模式)以使其正确。

这经常需要我返回命令,跳转到命令中间的位置并进行更改。我可以在 vi 模式下快速完成此操作,但仍然发现它很慢且容易出错。

有时我会将这样的命令保存到文件中,然后编辑该文件,然后再次运行它等等,但这让我思考......

有没有更具交互性的方式来迭代 bash 命令?在某种程度上更像 REPL,更容易编辑命令的输入?

例如,假设我正在迭代以下命令。有什么简单的方法可以更新“test”、“super”和“java$”,而无需使用 vi 模式跳回命令或在脚本中编辑它?

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

另一个例子可能是我对远程服务器运行 curl,并且也想替换不同的参数。有时我会设置变量,然后将它们传递给 curl,如下所示:

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

但是我发现这在我的历史记录中搜索设置变量的命令等太多了,因为这变得更加复杂。

答案1

我确信它可以改进,但我只是将它们组合在一起,以允许使用子 shell 在命令中间提示。因此,在下面的简单示例中,每次运行它时,它都会以交互方式询问我 2 个参数,然后输出该结果。

$ 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?

如果我第二次运行它,它会记住我输入的内容(它会将这些内容保存在 中的一个临时文件中/tmp)。可以通过传递“no”作为第二个参数来禁用此功能。

$ 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?

笔记:

  • 可以通过运行删除所有 tmp 文件ask clear
  • 可以通过运行来显示帮助ask help
  • 这需要 bash 4.x,因为read -i旧版 bash 中没有这个功能。这是为了向 ask 提供默认值。您可以使用 homebrew 升级 bash。

这是脚本!

#!/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

相关内容