shell 脚本如何从外部编辑器获取输入(就像 Git 那样)?

hjk*_*kml 2 git vim bash shell

我想要一个 shell 脚本暂停,从外部编辑器获取输入,然后恢复。像这样的伪代码作为一个最小的例子:

testScript(){
  content=""
  # set value of content using vim...
  echo "$content"
}
Run Code Online (Sandbox Code Playgroud)

我不想使用包,只想使用 Bash。

gni*_*urf 5

#!/bin/bash

# This uses EDITOR as editor, or vi if EDITOR is null or unset
EDITOR=${EDITOR:-vi}

die() {
    (($#)) && printf >&2 '%s\n' "$@"
    exit 1
}

testScript(){
  local temp=$(mktemp) || die "Can't create temp file"
  local ret_code
  if "$EDITOR" -- "$temp" && [[ -s $temp ]]; then
      # slurp file content in variable content, preserving trailing blank lines
      IFS= read -r -d '' content < "$temp"
      ret_code=0
  else
      ret_code=1
  fi
  rm -f -- "$temp"
  return "$ret_code"
}

testScript || die "There was an error when querying user input"
printf '%s' "$content"
Run Code Online (Sandbox Code Playgroud)

如果您不想保留尾随空白行,请替换

IFS= read -r -d '' content < "$temp"
Run Code Online (Sandbox Code Playgroud)

content=$(< "$temp")
Run Code Online (Sandbox Code Playgroud)

您还可以添加一个陷阱,以便在临时文件创建和删除之间脚本停止的情况下删除临时文件。

我们正在尝试检查整个过程中一切是否顺利:

  • testScript如果我们无法创建临时文件,该函数会提前中止;
  • 当我们编辑临时文件时,我们检查编辑器是否正常运行并结束,然后我们还通过检查文件是否存在且不为空来显式检查用户是否输入了至少一个字符[[ -s $temp ]]
  • 我们使用内置的read. 使用这种方式,我们不会修剪任何前导或尾随空白,也不修剪尾随换行符。该变量content 包含尾随换行符!你可以用${content%$'\n'};修剪它 另一种可能性是不read完全使用 but content=$(< "$temp")
  • 在继续之前,我们明确检查函数是否返回且没有错误。