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

时间:2015-02-24 20:27:47

标签: git bash shell vim

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

testScript(){
  content=""
  # set value of content using vim...
  echo "$content"
}

我不想使用包,只是Bash。

2 个答案:

答案 0 :(得分:2)

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

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

IFS= read -r -d '' content < "$temp"

content=$(< "$temp")

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

我们试图在整个过程中检查一切是否正常:

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

答案 1 :(得分:0)

Pigan退出Etan Reisner的建议你可以设置一个/ tmp文件用于编辑。然后阅读内容。除非该文件将用于在脚本的其他部分聚合某些数据,否则您可能希望在设置$ content var时清除内容。

testScript() {
  content=""
  contentFile=/tmp/input
  vim $contentFile
  content=`cat $contentFile`
  cat /dev/null > $contentFile
}

testScript
echo $content