Reputation: 253
I'd like a shell script to pause, get input from an external editor, and then resume. Something like this pseudocode for a minimal example:
testScript(){
content=""
# set value of content using vim...
echo "$content"
}
I don't want to use a package, just Bash.
Upvotes: 2
Views: 1049
Reputation: 46843
#!/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"
If you don't want to preserve trailing blank lines, replace
IFS= read -r -d '' content < "$temp"
with
content=$(< "$temp")
You could also add a trap so that the temp file is removed in case script is stopped between the temp file creation and removal.
We're trying to check that everything is going all right through the whole process:
testScript
aborts early if we can't create a temp file;[[ -s $temp ]]
.read
. Used this way, we are not trimming any leading or trailing blanks, nor trailing newlines. The variable content
contains the trailing newline! you can trim it with ${content%$'\n'}
; another possibility is to not use read
altogether but content=$(< "$temp")
.Upvotes: 5
Reputation: 13
Piggy backing off of Etan Reisner's suggestion you could just set a /tmp file to be used for the editing. Then read in the contents. Unless that file is going to be used to aggregate some data during other portions of your script you probably want to clear the contents when you're done setting the $content var.
testScript() {
content=""
contentFile=/tmp/input
vim $contentFile
content=`cat $contentFile`
cat /dev/null > $contentFile
}
testScript
echo $content
Upvotes: 0