2

Very often, I need to quickly type some lines of characters (for instance for simplifying a mathematical expression) and then discard the whole stuff. Of course, I generally have several running sessions of my text editor, and I can do it there. I have also been using the following system; I type echo " in a terminal (running bash) and then type anything; when I am done, I type a closing ".

Yesterday, I decided to add something more elegant in my .bashrc and I created the following alias:

# write junk on the terminal (stop with a line containing only "." )
# alias scratch="awk '/^\.$/{exit}'"
# alias scratch="sed -ne '/^\.$/q'"
alias scratch='grep -q "^\.$"'

You can see above three variants doing the same thing: I type scratch, then type whatever I want to type, and I end with a line containing only . (dot).

I am very happy with that, but I also thought at the following variant:

alias scratch="cat - > /dev/null << ."

which does the same thing with an initial prompt > at the beginning of each line.

Then, I wondered how I could use the PS2 environment variable for changing this prompt, and I couldn't get anything fully working. Of course, the current PS2 prompt should be restored when I am done. How can I set the prompt for this variant of my scratch alias to any arbitrary string during the time of the "scratch" session only?

  • Not an answer to your question, but I use something like cat > /dev/null all the time; you could alias scratch='cat > /dev/null' and end with a Control-D or Control-C. – Jeff Schaller Jun 10 '19 at 14:53
1

I'm not entirely sure what this is useful for (compared to nano, vim or any editor you fancy), but... does it need an alias?

$ <<.
> foo
> bar
> baz
> .

Just " would be even shorter but there'll be an error message...

$ "
> oh
> ah
> ui
> "
bash: $'\noh\nah\nui\n': command not found

Note that these things are not really gone...

$ history
  497  <<.
foo
bar
baz
.

If that bothers you, disable history first or clear it afterwards.

For a custom PS2 prompt, it's difficult since (at least for Bash) it has to be set to the parent shell. If you set it in a subshell, it'll be ignored. You can kind of work around it by starting an explicit shell instance like this...

$ PS1=@_ PS2=:_ bash --norc
@_<<.
:_hey
:_.
@_exit
$

But at this point it would make more sense to write a dedicated scratch and discard program.

Different approach, not using the PS2 prompt at all:

$ while read -p ":-> " ; do : ; done
:-> hey
:-> how 
:-> do

Only you can't use '.' to get out here. Well, you could easily add that as a condition...

$ alias scratch='(var=_; while read -r -p ":-> " var; do [ "$var" == . ] && break; done)'
$ scratch
:-> a
:-> b
:-> c
:-> .

However, you can also just get out by sending EOF with Ctrl+D.

| improve this answer | |
  • Thank you for the <<. idea; it is even shorter to type than my current alias! – Thomas Baruchel Jun 10 '19 at 15:17
1

Use read to read input line by line. You can specify a prompt. The following snippet reads lines and ignores their content until a line consisting of optional whitespace around a single dot, or until you press Ctrl+D on a blank line.

scratch () {
  local line
  while [[ "$line" != "." ]] && read -r -e -p "scratch> " line; do :; done
}
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.