What's new

Any way to clear command from terminal history (up/down arrow)

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

FreshJR

Very Senior Member
Every time you execute a command it gets stored in two locations.
1) Stored in memory ( struct line_input_t -> char *history[MAX_HISTORY + 1]; )
2) Stored in HISTFILE (/tmp/home/root/.ash_history)​

I have the following alias that I use often
clr='clear && printf "\e[3J" '​

The following scenario has been bugging me enough for me to look into it.
1) Execute command that fills up screen
2) Issue clr
3) Press up arrow
**4**) clr command cluttering history. I wish clr could be ignored
I thought it would be simple to purge it from the .ash_history file, but I found NO way to repopulate the memory location with the trimmed contents of the modified HISTFILE. Well besides restarting terminal, but that really isn't an option.

I need to repopulate the history memory location as that is what is referenced when pressing UP/DOWN arrow.

I dug into the source code and confirmed this

Code:
//ash.c
//ash terminal built in commands

    //history terminal command executing corresponding historycmd function
    static const struct builtincmd builtintab[] = {
            { BUILTIN_NOSPEC        "history" , historycmd },
        };

    //ash terminal history actual function -- ignores parameters :(
    historycmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
    {
        show_history(line_input_state);
        return EXIT_SUCCESS;
    }

//lineedit.c
//defines how terminal acts
    extern struct lineedit_statics *const lineedit_ptr_to_statics;    //terminal parameters, current input, cursor location, etc
                                                                     //was defined in a hacky way to make a CONST declaration gain R/W ability
    #define S         (*lineedit_ptr_to_statics)                        //short way to access terminal parameters
    #define state   (S.state)                                        //contains command history
                                                                    //    note: state member is of structure type "line_input_t"


    // loads history present from hist_file when cnt_history is empty (happens upon terminal start)
    # if ENABLE_FEATURE_EDITING_SAVEHISTORY
        if (state->hist_file)
            if (state->cnt_history == 0)
                load_history(state);
    # endif


    // no access to this from ash terminal
    static void load_history(line_input_t *st_parm)
    {
        ...
        ...
    }

Unfortuantly our history command does NOT take arguments.
https://ss64.com/bash/history.html

I would need to execute "history -r" according to that MAN page.
We already have the "-r" functionality coded in the source code, the problem is that there is no command/argument to reach the load_history function that is normally invoked by "history -r"

We have many brilliant people on this form. Has anyone hacked together a workaround?!?!
I tried but failed, is recompiling ash and replacing it the only way?
 
Last edited:
I'm really struggling to understand why this is of any concern whatsoever :confused:. So you see the clr command when you go back through the history with the up-arrow, so what? I'm not being rude, I truly don't see why this is an inconvenience. Are you issuing a clr every other input? Do you really look back in the history that much?
 
I'm really struggling to understand why this is of any concern whatsoever :confused:. So you see the clr command when you go back through the history with the up-arrow, so what? I'm not being rude, I truly don't see why this is an inconvenience. Are you issuing a clr every other input? Do you really look back in the history that much?

Yes I issue it so frequently that I tried to figure to alleviate the inconvenience.
I find it hard to scroll between data if the terminal goes too far back into the past.

On the bigger picture, I only mess around with the router every so often so it's probably wont bother me again for another few months.

Typical workflow


1) command | grep "ABC"
2) lets see what changed
3) clr, up, enter
6) crap, reissued clr
7) up, up, up, enter

I have clr on a macro that bound to one key press, so step 3 happens faster than I think.
 
Last edited:
Hmmm, I see. I think the only solution would be to compile your own version that filtered out the commands on input. Even if the "history -r" option was available it still wouldn't help you because it just adds to the end of the current history, it doesn't overwrite it.
 
Hmmm, I see. I think the only solution would be to compile your own version that filtered out the commands on input. Even if the "history -r" option was available it still wouldn't help you because it just adds to the end of the current history, it doesn't overwrite it.

In the MAN page it would probably have to be preceded by -w.

The function I found I think overwrote the memory location instead of appending it from what I remember.
 
-w only writes the current history to a file it doesn't clear it, -c will clear the history. So you'd have to 1) write the file, 2) filter out the clr's, 3) clear the history, 4) reload the history, and do all of this as part of your clr alias. But you don't have those options so it's academic anyway.
 
In your /jffs/init-start, you can do "mkdir -p /root/.ash_history", to prevent shell commands being written to the filesystem. The password to my USB storage device is there? And if you've changed your home directory to /opt, then the .ash_history file will be written there as well. Deleting this file is not secure, you'd need a secure wipe program to do that.

Here's more info on a Busybox patch to the source code, to securely wipe memory of said shell commands.
https://github.com/RMerl/asuswrt-merlin/pull/1302
 
In your /jffs/init-start, you can do "mkdir -p /root/.ash_history", to prevent shell commands being written to the filesystem. The password to my USB storage device is there? And if you've changed your home directory to /opt, then the .ash_history file will be written there as well. Deleting this file is not secure, you'd need a secure wipe program to do that.

Here's more info on a Busybox patch to the source code, to securely wipe memory of said shell commands.
https://github.com/RMerl/asuswrt-merlin/pull/1302
I don't think this is relevant to what the OP was asking.
 
What does printf "\e[3J" do? (I don't see any result in PuTTY)

If you only want to clear the screen, you could use CTRL+L to do that without adding anything to the history?
 
I don't think this is relevant to what the OP was asking.
Oops my bad I didn't fully read it. Now my understanding is he wants "history -r" to load .ash_history?

See how this guy implemented "history -c" in this Busybox patch. Maybe use it as an example for how to implement "history -r"? Apparently, you must update both Ash and Hush when adding a new command line argument.
https://github.com/RMerl/asuswrt-me...5162683#diff-0d8a305e46df6c26e954464da8b7ad8f
 
Oops my bad I didn't fully read it. Now my understanding is he wants "history -r" to load .ash_history?
No, that's not it.


What does printf "\e[3J" do? (I don't see any result in PuTTY)

If you only want to clear the screen, you could use CTRL+L to do that without adding anything to the history?
This seems to be the answer (CTRL+L). The printf "\e[3J" clears the scrollback buffer, which seems rather unnecessary and actually undesirable IMHO.

This (CTRL-L) is aesthetically a much better solution because you are interacting directly with the terminal emulator, rather than issuing a command to a remote system (the router) and getting that system to send escape codes back. So it avoids the whole issue of trying to "hide" the command sent to the router.
 
Last edited:
The printf "\e[3J" clears the scrollback buffer, which seems rather unnecessary and actually undesirable IMHO.

It's not really all that undesirable.
Just do the following,

1) cat a long file
2) issue a screen clear
3) cat a long file again

once you scroll you won't know if you are looking at the 1rst or 2nd cat output. The terminal really blends everything together.

I found a solution, Putty already has both features implemented client side!

1) Ctrl+L for screen clear
2) Ctrl+Right Click -> Clear Scrollback for scrollback clear

It is unfortunate that "Clear Scrollback" did not come out of the box with a keyboard shortcut.
My current and safest approach will be to recompile Putty and modify the Ctrl+L hotkey to issue both "Screen Clear & Scroll Back" to the terminal.

--
As for the history approach. More fully featured terminals have similar functionality. You can simply add prefixes to HISTIGNORE and any line starting with a user defined prefix wouldn't be logged. A common use of this feature is to not log passwords in plaintext or in my case it would be not to log the damned clr alias.
--

@XIII as for what the printf does. It simply sends a command to the terminal. It functions exactly the same like echo.
printf is 99% similar to echo except it does not append a new line after it is finished running. Run the following code and observe identical functionality, except this time with an annoying new line.
Code:
clear && echo -e '\e[3J'

Once the terminal receives certain commands it can apply colors, move the cursor, clear the screen, clear the scrollbar, etc.

More specifically the "\e[3J" command can be broken down into 4 sections.
\e = ESCAPE KEY , [ char, 3 char, J char

Once the terminal receives { ESC + [ + 3 + J }, it clears the scroll bar. More commands can be found here.
https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences

Just the two key { ESC + [ } portion of any command can be further abbreviated as CSI (Control Sequence Initiator). As such, you can think of the printf comannd causing the terminal to execute Control Sequence 3 J.

Similarly when you press LeftArrow behinds the scenes a CSI D command is being sent to the terminal. The CSI D command in its simplest form is the same as sending { ESC [ D }.

For even more trivia, the ESC character can alternatively be abbreviated in caret notation as ^[.

If you ever "glitch" the terminal and see ^[[D you can deconstruct that into "ESC [ D" or "CSI D". Seeing ^[[D means you just pressed LeftArrow while in glitched mode.
 
Last edited:
It's not really all that undesirable.
Just do the following,

1) cat a long file
2) issue a screen clear
3) cat a long file again

once you scroll you won't know if you are looking at the 1rst or 2nd cat output. The terminal really blends everything together.
I don't follow the logic of this argument. You're saying that in some circumstances the scrollback buffer is too full to be useful. OK. So your solution is to always erase the scrollback buffer completely. Why not simply not look at the scrollback buffer in that case? At least it would still be available for those situations where it does contain useful information. Alternatively, if you really don't want the scrollback buffer just turn it off in the options.

As a side note, what are you using for your macro manager? You said you've bound your clr command to a hotkey. Perhaps you could bind CTRL-L and CSI3J to it instead. It might be less hassle than recompiling PuTTY.
 
As a side note, what are you using for your macro manager? You said you've bound your clr command to a hotkey. Perhaps you could bind CTRL-L and CSI3J to it instead. It might be less hassle than recompiling PuTTY.

Nothing fancy, it's just an AutoIt script that remaps the additional keys that almost all keyboards have.
I already tried sending Putty the keycodes and it didn't work.

I also have a basic C++ version of the same code (listens for hotkey & executes macros) but I switched to AutoIT since it is stupidly simple to make app specific macros and quick modifications.

My fav macro is a one key toggle audio output from headphones to speakers and back, since windows makes that process WAYY to convoluted and drawn out.

I know AutoIt can easily invoke the context menu and click the context item, but I would perfer not to even see it for a split second.
 
Last edited:

Support SNBForums w/ Amazon

If you'd like to support SNBForums, just use this link and buy anything on Amazon. Thanks!

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top