5

I want to make a simple script to delete a line from bash_history, based on user input of the line number.

echo -n "Delete History Line Number: "
read num
history -d $num

The error is "history position out of range" (which it shouldn't be, I'm using a number within range).

Why doesn't this work?

5
  • 1
    A question like this would be answered on Stack Overflow, if you described the specific problem.
    – gparyani
    Sep 24, 2013 at 21:57
  • Are you getting an error output? If so, what specifically?
    – nerdwaller
    Sep 24, 2013 at 22:01
  • The error is "history position out of range" (which it shouldn't be, I'm using a number within range)
    – Adam
    Sep 24, 2013 at 22:24
  • 1
    You have to read bash's source to solve the riddle.
    – ott--
    Sep 24, 2013 at 22:30
  • Why isn't this the appropriate place to ask this question? It's specific and brief and seems to meet all the guidelines listed here: superuser.com/about.
    – Adam
    Sep 24, 2013 at 22:55

3 Answers 3

9

There are two reasons why your script will not work as intended:

  1. The bash environment for a running script is "non-interactive" and does not have the history features enabled.
  2. The bash environment for a running script is independent from the environment you are interactively working in.

Depending on your use case the easiest solution might be to source the script, instead of executing. See the SU post explaining the difference of sourcing and executing for more information.

0

Through the source method its working,

my source_file.sh contain

# cat /root/source_file.sh
#!/bin/bash
history -d $1

and my master_file.sh have below lines

# cat /root/master_file.sh
#!/bin/bash
if [ "$1" == "" ]; then
echo -e "Enter command number from history(syntax: source script_name.sh xxxx)"
else
source /root/source_file.sh && echo -e "Line number $1 removed successfully"

fi

we can test the script now,

# source /root/master_file.sh
Enter command number from history(syntax: source script_name.sh xxxx)

okay lets add the line number

# history | tail -n 10
 1193  grep disable /etc/sysconfig/selinux
 1194  grep enforce /etc/sysconfig/selinux
 1195  sestatus
 1196  arch
 1197  uname -r
 1198  uname -a
 1199  history
 1200  history | tail -n 10
 1201  pwd
 1202  history | tail -n 10

Lets remove the line 1196

# source /root/master_file.sh 1196
Line number 1196 removed successfully

 

# history | tail -n 10
 1194  grep enforce /etc/sysconfig/selinux
 1195  sestatus
 1196  uname -r
 1197  uname -a
 1198  history
 1199  history | tail -n 10
 1200  pwd
 1201  history | tail -n 10
 1202  source /root/master_file.sh 1196
 1203  history | tail -n 10
0

If the 'history position out of range' occurs during a loop this solution might help:

The following command will invert the output of the history command:

history | tac

Use this in a for loop to remove all history command that contain "YOUR_SEARCHSTRING":

for ln in $( history | tac | grep "YOUR_SEARCHSTRING" | cut -f2 -d' '); do history -d $ln; done

Using 'tac' to revert history will avoid having 'out of range' errors.

0

You must log in to answer this question.

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