8

I have a script that allows me to log random thoughts while working on a project. In the terminal I would add a new log entry by running

$ @ "some random thought"

where @ is just an alias for my script.

Say my terminal is in this state:

$ ls /var/tmp
somefile.ext
another-file.l
$ _

After running my script, it would look like this:

$ ls /var/tmp
somefile.ext
another-file.l
$ @ "some random thought"
$ _

Now, I do not want that line ($ @ "some random thought") to stay on the screen after I enter it. I just want the script to run and leave no trace on the screen (some things are personal and some people might see my terminal). I also do not want to clear the entire screen.

Do you think this is possible? I am using Iterm2 if this helps.

NB: I know how to handle history so that it doesn't record my log entries. I just want to leave no trace on the screen.

3
  • As I responded to @mutzmatron, this would not help in my case.
    – whonoes
    Dec 17, 2013 at 12:12
  • Yeah, I just also noticed that.
    – user37607
    Dec 17, 2013 at 12:16
  • I doubt there's an easy way to erase the last line of terminal. The easiest solution would probably be writing your own shell.
    – user37607
    Dec 17, 2013 at 12:22

4 Answers 4

8

Instead of having a command to enter your thought, you could define a widget for that. In zsh:

thought() { 
  print -r -- $BUFFER >> ~/.thoughts
  # or: your-script $BUFFER
  BUFFER=
  zle -M 'thought recorded'
}
zle -N thought
bindkey '^T' thought

Then press Ctrl-T to add the content of the buffer to your ~/.thoughts file and clear it afterwards (BUFFER=). Then, you don't have to worry about quoting.

Another approach could be to use interactive comments:

setopt interactive_comments
alias '@=:;#'
preexec() {
  [[ $1 = @* ]] && {
    print -r -- ${1#* } >> ~/.thoughts
    # or: your-script ${1#* }
    echoti cuu1
  }
}

Again, no problem with quoting, but that only works for single line thoughts. (the echoti cuu1 takes care of clearing that line by moving the cursor up).

5
  • Doesn't this sidestep the question...?
    – jmetz
    Dec 17, 2013 at 12:47
  • Thanks Stephane, but I already have a working script (python) which does a little more than logging strings. Your solution means I have to trash all out and it's a bit convoluted for my simple case :) Mutzmatron's answer solved my issue.
    – whonoes
    Dec 17, 2013 at 13:05
  • I upvoted this answer after posting mine because I think it's less kludgy than a terminal hack. But there's no accounting for taste!
    – Alexios
    Dec 17, 2013 at 13:44
  • @whonoes, just add a call to "your-script" in there, the print >> ~/.thoughts was just an example so that anybody can test it. Dec 17, 2013 at 14:39
  • @stephane, this indeed is a more elegant solution; I just want to solve everything in my script (which is too simple to have a widget as a dependency when I can avoid that, even by employing a terminal hack)
    – whonoes
    Dec 20, 2013 at 8:44
6

Warning, this is a horrible, horrible hack (but then, the entire request is a bit of a hack). :)

Here's something that'll work on most terminals, including the braindead MS-DOS ‘ANSI.SYS’ emulator. Won't work on dumb terminals, of course (but nothing will):

tput sc
echo "This will be hidden."
sleep 5
tput rc; tput cuu 1; tput ed

Obviously, this is an example. Get rid of the echo and sleep and replace it with your command. Here's how it works:

  • tput sc saves the current co-ordinates of the cursor on-screen,
  • tput rc moves the cursor back to the stored co-ordinates. Now, the screen may have scrolled, so the sensitive stuff will be on the line above the saved one. So,
  • tput cuu 1 moves the cursor one row up. (if you feel especially paranoid, feel free to increase the number.
  • Finally, tput ed clears to the end of the screen (i.e. clears from the cursor to the end of line, then from the cursor to the bottom of the screen).

This will fail comically if the screen scrolls by a lot because sc doesn't know about scrolling, just screen co-ordinates.

tput is terminal-agnostic, so it'll work as long as your particular terminal is listed in the terminfo database and the TERM variable is correctly set.

1
  • Upvoted for portability - works great indeed!
    – whonoes
    Dec 20, 2013 at 8:39
4

You could try overwriting the previous line, which has already been answered;

How to change the contents of a line on the terminal as opposed to writing a new one?

For example (modified from original answer):

prompt% echo -n "Old line"; echo "\033[1A\033[1A" "new line"

Will display only:

prompt% new line

As the output. Adding more \033[1A sequences removes more lines.

Caveat: This doesn't work on all terminals.

14
  • My script does not output anything. I want to remove the actual command from the screen, not it's output.
    – whonoes
    Dec 17, 2013 at 11:41
  • Yes, that will overwrite the last script output line; with your example, I would like for prompt% echo -n "Old line"; echo -e "\e[0K\r new line" to dissapear from the terminal.
    – whonoes
    Dec 17, 2013 at 12:08
  • You're right, I updated my answer with the correct terminal sequence.
    – jmetz
    Dec 17, 2013 at 12:13
  • 1
    Thank you mutzmatron, this solves my issue. One caveat would be that if the string I pass to the script has more than one line (the text wraps in the terminal), only the last one will be deleted. Adding more \033[1A sequences would work, but then if I add a string with just one line, more than one line will be removed from the terminal. Still, good enough for my case, I will accept your answer, thanks!
    – whonoes
    Dec 17, 2013 at 13:00
  • 1
    I just posted the answer I was composing, and you beat me to it. My own solution uses tput, not terminal directives, so it's more portable across terminals. It works with multi-line output, too — but it breaks if the output scrolls a lot.
    – Alexios
    Dec 17, 2013 at 13:45
0

Well, if it's just some random thought rather than actual command, then you can do so by adding space before the thought. It will exclude this command from getting into history

satish@Satish:/tmp $ echo "I'm in history"
I'm in history
satish@Satish:/tmp $  echo "I'm not"
I'm not
satish@Satish:/tmp $ history | tail -n 3
 1887  sudo su -
 1888  echo "I'm in history"
 1889  history | tail -n 3
satish@Satish:/tmp $ 
3
  • 2
    The OP wants the command to not be present in the terminal, not the history.
    – jmetz
    Dec 17, 2013 at 11:47
  • As mentioned in the question, history is not a problem, I can manage that. With your example, I would like this line satish@Satish:/tmp $ echo "I'm not" to be hidden from the terminal after I run it.
    – whonoes
    Dec 17, 2013 at 12:09
  • Yeah...I got it....will see if I can find solution for this. And then will post here :)
    – SHW
    Dec 17, 2013 at 12:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .