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?
-
1A question like this would be answered on Stack Overflow, if you described the specific problem.gparyani– gparyani2013年09月24日 21:57:21 +00:00Commented Sep 24, 2013 at 21:57
-
Are you getting an error output? If so, what specifically?nerdwaller– nerdwaller2013年09月24日 22:01:05 +00:00Commented 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– Adam2013年09月24日 22:24:46 +00:00Commented Sep 24, 2013 at 22:24
-
1You have to read bash's source to solve the riddle.ott--– ott--2013年09月24日 22:30:09 +00:00Commented 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– Adam2013年09月24日 22:55:48 +00:00Commented Sep 24, 2013 at 22:55
3 Answers 3
There are two reasons why your script will not work as intended:
- The bash environment for a running script is "non-interactive" and does not have the history features enabled.
- 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.
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
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.