How to 'hash -r' and refresh all shells?
Clash Royale CLAN TAG#URR8PPP
up vote
3
down vote
favorite
This is related to What is the purpose of the hash command? After installing a program I am looking for a way to tell all open shells to update their cache. I often have 6 to 8 of them open and I don't want to have to run hash -r
8 or 10 times. Anything more than once is a waste of time and effort.
After installing a program in one shell, is it possible to either (1) have all shells rebuild their view of cached programs; or (2) rebuild the table and use that table for all other shells? If it is possible, then how do we do it?
Here is the relevant section of man 1 hash
, but it does not discuss how to achieve results globally.
hash [-lr] [-p filename] [-dt] [name]
Each time hash is invoked, the full pathname of the command name
is determined by searching the directories in $PATH and rememâÂÂ
bered. Any previously-remembered pathname is discarded. If the
-p option is supplied, no path search is performed, and filename
is used as the full filename of the command. The -r option
causes the shell to forget all remembered locations. The -d
option causes the shell to forget the remembered location of
each name. If the -t option is supplied, the full pathname to
which each name corresponds is printed. If multiple name arguâÂÂ
ments are supplied with -t, the name is printed before the
hashed full pathname. The -l option causes output to be disâÂÂ
played in a format that may be reused as input. If no arguments
are given, or if only -l is supplied, information about rememâÂÂ
bered commands is printed. The return status is true unless a
name is not found or an invalid option is supplied.
bash command-line
 |Â
show 5 more comments
up vote
3
down vote
favorite
This is related to What is the purpose of the hash command? After installing a program I am looking for a way to tell all open shells to update their cache. I often have 6 to 8 of them open and I don't want to have to run hash -r
8 or 10 times. Anything more than once is a waste of time and effort.
After installing a program in one shell, is it possible to either (1) have all shells rebuild their view of cached programs; or (2) rebuild the table and use that table for all other shells? If it is possible, then how do we do it?
Here is the relevant section of man 1 hash
, but it does not discuss how to achieve results globally.
hash [-lr] [-p filename] [-dt] [name]
Each time hash is invoked, the full pathname of the command name
is determined by searching the directories in $PATH and rememâÂÂ
bered. Any previously-remembered pathname is discarded. If the
-p option is supplied, no path search is performed, and filename
is used as the full filename of the command. The -r option
causes the shell to forget all remembered locations. The -d
option causes the shell to forget the remembered location of
each name. If the -t option is supplied, the full pathname to
which each name corresponds is printed. If multiple name arguâÂÂ
ments are supplied with -t, the name is printed before the
hashed full pathname. The -l option causes output to be disâÂÂ
played in a format that may be reused as input. If no arguments
are given, or if only -l is supplied, information about rememâÂÂ
bered commands is printed. The return status is true unless a
name is not found or an invalid option is supplied.
bash command-line
If you installed a program in one of the $PATH directories, you shouldn't even need to rehash. Curious why you're using -r, as well.
â Jeff Schaller
Oct 13 '17 at 23:59
@Jeff - You certainly need it even when installing on$PATH
; see, for example, Path not being honored? on OS X stack exchange. As for-r
, I staterted using it to try and get Bash to forget the old version of the program installed in/usr/bin
(re: OS X question). If you have another recommendation, then I'd be happy to use it.
â jww
Oct 14 '17 at 0:04
You're replacing an existing $PATH'd binary with a different one of the same name?
â Jeff Schaller
Oct 14 '17 at 0:05
@jeff - Yes. For example, I might be upgrading (displacing?)emacs
oropenssl
located in/usr/bin
with a new one located in/usr/local/bin
. I never overwrite or delete what's in/usr/bin
. I install something new in/usr/local/bin
.
â jww
Oct 14 '17 at 0:07
1
@JeffSchaller I added a pseudo-script at the bottom of my solution which I think produces something like what jww is experiencing.
â igal
Oct 16 '17 at 13:47
 |Â
show 5 more comments
up vote
3
down vote
favorite
up vote
3
down vote
favorite
This is related to What is the purpose of the hash command? After installing a program I am looking for a way to tell all open shells to update their cache. I often have 6 to 8 of them open and I don't want to have to run hash -r
8 or 10 times. Anything more than once is a waste of time and effort.
After installing a program in one shell, is it possible to either (1) have all shells rebuild their view of cached programs; or (2) rebuild the table and use that table for all other shells? If it is possible, then how do we do it?
Here is the relevant section of man 1 hash
, but it does not discuss how to achieve results globally.
hash [-lr] [-p filename] [-dt] [name]
Each time hash is invoked, the full pathname of the command name
is determined by searching the directories in $PATH and rememâÂÂ
bered. Any previously-remembered pathname is discarded. If the
-p option is supplied, no path search is performed, and filename
is used as the full filename of the command. The -r option
causes the shell to forget all remembered locations. The -d
option causes the shell to forget the remembered location of
each name. If the -t option is supplied, the full pathname to
which each name corresponds is printed. If multiple name arguâÂÂ
ments are supplied with -t, the name is printed before the
hashed full pathname. The -l option causes output to be disâÂÂ
played in a format that may be reused as input. If no arguments
are given, or if only -l is supplied, information about rememâÂÂ
bered commands is printed. The return status is true unless a
name is not found or an invalid option is supplied.
bash command-line
This is related to What is the purpose of the hash command? After installing a program I am looking for a way to tell all open shells to update their cache. I often have 6 to 8 of them open and I don't want to have to run hash -r
8 or 10 times. Anything more than once is a waste of time and effort.
After installing a program in one shell, is it possible to either (1) have all shells rebuild their view of cached programs; or (2) rebuild the table and use that table for all other shells? If it is possible, then how do we do it?
Here is the relevant section of man 1 hash
, but it does not discuss how to achieve results globally.
hash [-lr] [-p filename] [-dt] [name]
Each time hash is invoked, the full pathname of the command name
is determined by searching the directories in $PATH and rememâÂÂ
bered. Any previously-remembered pathname is discarded. If the
-p option is supplied, no path search is performed, and filename
is used as the full filename of the command. The -r option
causes the shell to forget all remembered locations. The -d
option causes the shell to forget the remembered location of
each name. If the -t option is supplied, the full pathname to
which each name corresponds is printed. If multiple name arguâÂÂ
ments are supplied with -t, the name is printed before the
hashed full pathname. The -l option causes output to be disâÂÂ
played in a format that may be reused as input. If no arguments
are given, or if only -l is supplied, information about rememâÂÂ
bered commands is printed. The return status is true unless a
name is not found or an invalid option is supplied.
bash command-line
edited Oct 13 '17 at 23:59
Jeff Schaller
32.1k849109
32.1k849109
asked Oct 13 '17 at 21:55
jww
1,43132154
1,43132154
If you installed a program in one of the $PATH directories, you shouldn't even need to rehash. Curious why you're using -r, as well.
â Jeff Schaller
Oct 13 '17 at 23:59
@Jeff - You certainly need it even when installing on$PATH
; see, for example, Path not being honored? on OS X stack exchange. As for-r
, I staterted using it to try and get Bash to forget the old version of the program installed in/usr/bin
(re: OS X question). If you have another recommendation, then I'd be happy to use it.
â jww
Oct 14 '17 at 0:04
You're replacing an existing $PATH'd binary with a different one of the same name?
â Jeff Schaller
Oct 14 '17 at 0:05
@jeff - Yes. For example, I might be upgrading (displacing?)emacs
oropenssl
located in/usr/bin
with a new one located in/usr/local/bin
. I never overwrite or delete what's in/usr/bin
. I install something new in/usr/local/bin
.
â jww
Oct 14 '17 at 0:07
1
@JeffSchaller I added a pseudo-script at the bottom of my solution which I think produces something like what jww is experiencing.
â igal
Oct 16 '17 at 13:47
 |Â
show 5 more comments
If you installed a program in one of the $PATH directories, you shouldn't even need to rehash. Curious why you're using -r, as well.
â Jeff Schaller
Oct 13 '17 at 23:59
@Jeff - You certainly need it even when installing on$PATH
; see, for example, Path not being honored? on OS X stack exchange. As for-r
, I staterted using it to try and get Bash to forget the old version of the program installed in/usr/bin
(re: OS X question). If you have another recommendation, then I'd be happy to use it.
â jww
Oct 14 '17 at 0:04
You're replacing an existing $PATH'd binary with a different one of the same name?
â Jeff Schaller
Oct 14 '17 at 0:05
@jeff - Yes. For example, I might be upgrading (displacing?)emacs
oropenssl
located in/usr/bin
with a new one located in/usr/local/bin
. I never overwrite or delete what's in/usr/bin
. I install something new in/usr/local/bin
.
â jww
Oct 14 '17 at 0:07
1
@JeffSchaller I added a pseudo-script at the bottom of my solution which I think produces something like what jww is experiencing.
â igal
Oct 16 '17 at 13:47
If you installed a program in one of the $PATH directories, you shouldn't even need to rehash. Curious why you're using -r, as well.
â Jeff Schaller
Oct 13 '17 at 23:59
If you installed a program in one of the $PATH directories, you shouldn't even need to rehash. Curious why you're using -r, as well.
â Jeff Schaller
Oct 13 '17 at 23:59
@Jeff - You certainly need it even when installing on
$PATH
; see, for example, Path not being honored? on OS X stack exchange. As for -r
, I staterted using it to try and get Bash to forget the old version of the program installed in /usr/bin
(re: OS X question). If you have another recommendation, then I'd be happy to use it.â jww
Oct 14 '17 at 0:04
@Jeff - You certainly need it even when installing on
$PATH
; see, for example, Path not being honored? on OS X stack exchange. As for -r
, I staterted using it to try and get Bash to forget the old version of the program installed in /usr/bin
(re: OS X question). If you have another recommendation, then I'd be happy to use it.â jww
Oct 14 '17 at 0:04
You're replacing an existing $PATH'd binary with a different one of the same name?
â Jeff Schaller
Oct 14 '17 at 0:05
You're replacing an existing $PATH'd binary with a different one of the same name?
â Jeff Schaller
Oct 14 '17 at 0:05
@jeff - Yes. For example, I might be upgrading (displacing?)
emacs
or openssl
located in /usr/bin
with a new one located in /usr/local/bin
. I never overwrite or delete what's in /usr/bin
. I install something new in /usr/local/bin
.â jww
Oct 14 '17 at 0:07
@jeff - Yes. For example, I might be upgrading (displacing?)
emacs
or openssl
located in /usr/bin
with a new one located in /usr/local/bin
. I never overwrite or delete what's in /usr/bin
. I install something new in /usr/local/bin
.â jww
Oct 14 '17 at 0:07
1
1
@JeffSchaller I added a pseudo-script at the bottom of my solution which I think produces something like what jww is experiencing.
â igal
Oct 16 '17 at 13:47
@JeffSchaller I added a pseudo-script at the bottom of my solution which I think produces something like what jww is experiencing.
â igal
Oct 16 '17 at 13:47
 |Â
show 5 more comments
1 Answer
1
active
oldest
votes
up vote
0
down vote
Here is the TLDR solution: if you want to programmatically execute commands in pre-existing shell sessions then you can use the ttyecho
program.
WARNING: Note that this is not in general a safe operation and is sensitive to the state of each session. As user StephenKitt points out, this approach requires that each terminal session have a prompt that is waiting to receive input.
An alternative solution would be to effectively disable path-hashing by adding the PROMPT_COMMAND='hash -r'
statement to your ~/.bashrc
file. This won't affect currently running sessions, but will prevent this issue from arising in the future.
Finally, you could consider using a terminal multiplexer such as tmux, which supports executing commands in multiple terminals simultaneously.
A more detailed response follows.
It seems to me that the basic functionality that you're looking for is the ability to programmatically execute commands in other active shell sessions. I found that this question (of how to execute commands in other shell sessions) has been addressed elsewhere on this site, e.g.:
How do I run a command in a different tty?
Execute command in remote active terminal
It seems that the easiest way to execute commands in other active shell sessions is to use the ttyecho
utility. The ttyecho
program is a small, self-contained, single-file C program. Here are a couple of references to the ttyecho
source-code and documentation:
http://www.humbug.in/2010/utility-to-send-commands-or-data-to-other-terminals-ttypts/
https://github.com/osospeed/ttyecho
For completeness, here is the source code:
// ttyecho.c
// Original author: Pratik Sinha
// http://www.humbug.in/2010/utility-to-send-commands-or-data-to-other-terminals-ttypts/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <string.h>
#include <unistd.h>
void print_help(char *prog_name)
printf("Usage: %s [-n] DEVNAME COMMANDn", prog_name);
printf("Usage: '-n' is an optional argument if you want to push a new line at the end of the textn");
printf("Usage: Will require 'sudo' to run if the executable is not setuid rootn");
exit(1);
int main (int argc, char *argv)
char *cmd, *nl = "n";
int i, fd;
int devno, commandno, newline;
int mem_len;
devno = 1; commandno = 2; newline = 0;
if (argc < 3)
print_help(argv[0]);
if (argc > 3 && argv[1][0] == '-' && argv[1][1] == 'n')
devno = 2; commandno = 3; newline=1;
else if (argc > 3 && argv[1][0] == '-' && argv[1][1] != 'n')
printf("Invalid Optionn");
print_help(argv[0]);
fd = open(argv[devno],O_RDWR);
if(fd == -1)
perror("open DEVICE");
exit(1);
mem_len = 0;
for ( i = commandno; i < argc; i++ )
mem_len += strlen(argv[i]) + 2;
if ( i > commandno )
cmd = (char *)realloc((void *)cmd, mem_len);
else //i == commandno
cmd = (char *)malloc(mem_len);
strcat(cmd, argv[i]);
// strcat(cmd, " ");
if (newline == 0)
usleep(225000);
for (i = 0; cmd[i]; i++)
ioctl (fd, TIOCSTI, cmd+i);
if (newline == 1)
ioctl (fd, TIOCSTI, nl);
close(fd);
free((void *)cmd);
exit (0);
If you download the source code or copy-paste it to a file named ttyecho.c
, then you should be able to compile the program like so:
gcc ttyecho.c -o ttyecho
Once the program is compiled you should be able to use it to run any command you'd like in anther shell session. This included being able to programmatically run the hash -r
command in every active shell session. Here is one way to clear the hashed commands on all of the shell sessions on Mac OS X:
for _tty in /dev/ttys*; do ./ttyecho -n 'hash -r' $_tty; done
On a Linux machine you would do something like this instead:
for _tty in /dev/pts/*; do ./ttyecho -n 'hash -r' $_tty; done
Since some comments asked for a way to reproduce the issue, I've included the following script to illustrate how hashing can affect which program is executed.
# Create two bin directories
mkdir -p ~/local/bin1
mkdir -p ~/local/bin2
# Add the directories to the PATH, with bin2 preceding bin1
export PATH="$HOME/local/bin2:$HOME/local/bin1:$PATH"
# Create a test script and put it in the bin1 directory
cat <<HEREDOC > ~/local/bin1/test.sh
#!/bin/bash
# test.sh
echo "This is test #1, it's in ~/local/bin1"
HEREDOC
# Make the script executable
chmod +x ~/local/bin1/test.sh
# Verify that the script is found by using the "which" command
which test.sh
# Output:
#
# /home/username/local/bin1/test.sh
# Verify that the script is found by using the "type" command
type test.sh
# Output:
#
# test.sh is /home/username/local/bin1/test.sh
# Test the script
test.sh
# Output:
#
# This is test #1, it's in ~/local/bin1
# Now hash the test script
hash test.sh
# Verify that the script has been hashed by using the "type" command
type test.sh
# Output:
#
# test.sh is hashed (/home/username/local/bin1/test.sh)
# Now create a second test script and put it in bin2 to shadow the first
cat <<HEREDOC > ~/local/bin2/test.sh
#!/bin/bash
# test.sh
echo "This is test #2, it's in ~/local/bin2"
HEREDOC
# Make the second test script executable
chmod +x ~/local/bin2/test.sh
# Verify that the bin2 test script take priority over the bin1 test script
which -a test.sh
# Output:
#
# /home/username/local/bin2/test.sh
# /home/username/local/bin1/test.sh
which test.sh
# Output:
#
# /home/username/local/bin2/test.sh
# Try to run the test script
test.sh
# Ouput:
#
# This is test #1, it's in ~/local/bin1
# NOTE: Even though bin2/test.sh comes before bin1/test.sh in the PATH,
# it's bin1/test.sh that is executed. What's going on?
# Use the "type" command to see which script is being executed
type test.sh
# Output
#
# test.sh is hashed (/home/username/local/bin1/test.sh)
# NOTE: That explains the seeming contradiction.
# Clear the hashed command
hash -d test.sh
# Check that the hashed command has been cleared
type test.sh
# Output:
#
# test.sh is /home/username/local/bin2/test.sh
# Run the test.sh command
test.sh
# Output:
#
# This is test #2, it's in ~/local/bin2
I also found an alternative approach described elsewhere on this site:
- Disable bash's cache of executables in the path
The solution there was to use the PROMPT_COMMAND
variable to continuously clear the path cache, e.g. by adding the following line to your ~/.bashrc
:
PROMPT_COMMAND='hash -r'
Note that this will only affect new sessions and not your pre-existing sessions unless you also execute that command in those sessions.
Finally, you may want to consider using a terminal multiplexer such as tmux. Here is a relevant post from this site:
- Run command in multiple active shells simultaneously
1
How do you knowttyecho
is writing to a prompt thatâÂÂs waiting for a command? Say you have an IRC client in one terminal, an editor in another, and a shell with a complex command youâÂÂre working on (thatâÂÂs supposed to delete a bunch of files, for added fun)...
â Stephen Kitt
Oct 18 '17 at 15:16
@StephenKitt Is this a rhetorical question? If so, I should say that I don't think that this is a good idea. But it sounds like what the question was asking for, no? Personally I don't consider having to runhash -d
a few times to be much of an inconvenience.
â igal
Oct 18 '17 at 15:31
@StephenKitt I added an alternative solution (or approximate solution) that doesn't involve injecting commands into active sessions.
â igal
Oct 18 '17 at 15:42
1
No, itâÂÂs not a rhetorical question. ItâÂÂs an interesting approach, but it does have significant drawbacks, especially for someone like the OP with a bunch of long-lived shells lying around. You end up sending text strings to all terminals, not just âÂÂprogrammatically execut[ing] commands in other active shell sessionsâÂÂ. I would recommend adding the fact that you donâÂÂt think this is a good idea to the answer itself...
â Stephen Kitt
Oct 18 '17 at 15:43
@StephenKitt I completely agree. I've added a cautionary note, per your suggestion.
â igal
Oct 18 '17 at 15:56
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
Here is the TLDR solution: if you want to programmatically execute commands in pre-existing shell sessions then you can use the ttyecho
program.
WARNING: Note that this is not in general a safe operation and is sensitive to the state of each session. As user StephenKitt points out, this approach requires that each terminal session have a prompt that is waiting to receive input.
An alternative solution would be to effectively disable path-hashing by adding the PROMPT_COMMAND='hash -r'
statement to your ~/.bashrc
file. This won't affect currently running sessions, but will prevent this issue from arising in the future.
Finally, you could consider using a terminal multiplexer such as tmux, which supports executing commands in multiple terminals simultaneously.
A more detailed response follows.
It seems to me that the basic functionality that you're looking for is the ability to programmatically execute commands in other active shell sessions. I found that this question (of how to execute commands in other shell sessions) has been addressed elsewhere on this site, e.g.:
How do I run a command in a different tty?
Execute command in remote active terminal
It seems that the easiest way to execute commands in other active shell sessions is to use the ttyecho
utility. The ttyecho
program is a small, self-contained, single-file C program. Here are a couple of references to the ttyecho
source-code and documentation:
http://www.humbug.in/2010/utility-to-send-commands-or-data-to-other-terminals-ttypts/
https://github.com/osospeed/ttyecho
For completeness, here is the source code:
// ttyecho.c
// Original author: Pratik Sinha
// http://www.humbug.in/2010/utility-to-send-commands-or-data-to-other-terminals-ttypts/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <string.h>
#include <unistd.h>
void print_help(char *prog_name)
printf("Usage: %s [-n] DEVNAME COMMANDn", prog_name);
printf("Usage: '-n' is an optional argument if you want to push a new line at the end of the textn");
printf("Usage: Will require 'sudo' to run if the executable is not setuid rootn");
exit(1);
int main (int argc, char *argv)
char *cmd, *nl = "n";
int i, fd;
int devno, commandno, newline;
int mem_len;
devno = 1; commandno = 2; newline = 0;
if (argc < 3)
print_help(argv[0]);
if (argc > 3 && argv[1][0] == '-' && argv[1][1] == 'n')
devno = 2; commandno = 3; newline=1;
else if (argc > 3 && argv[1][0] == '-' && argv[1][1] != 'n')
printf("Invalid Optionn");
print_help(argv[0]);
fd = open(argv[devno],O_RDWR);
if(fd == -1)
perror("open DEVICE");
exit(1);
mem_len = 0;
for ( i = commandno; i < argc; i++ )
mem_len += strlen(argv[i]) + 2;
if ( i > commandno )
cmd = (char *)realloc((void *)cmd, mem_len);
else //i == commandno
cmd = (char *)malloc(mem_len);
strcat(cmd, argv[i]);
// strcat(cmd, " ");
if (newline == 0)
usleep(225000);
for (i = 0; cmd[i]; i++)
ioctl (fd, TIOCSTI, cmd+i);
if (newline == 1)
ioctl (fd, TIOCSTI, nl);
close(fd);
free((void *)cmd);
exit (0);
If you download the source code or copy-paste it to a file named ttyecho.c
, then you should be able to compile the program like so:
gcc ttyecho.c -o ttyecho
Once the program is compiled you should be able to use it to run any command you'd like in anther shell session. This included being able to programmatically run the hash -r
command in every active shell session. Here is one way to clear the hashed commands on all of the shell sessions on Mac OS X:
for _tty in /dev/ttys*; do ./ttyecho -n 'hash -r' $_tty; done
On a Linux machine you would do something like this instead:
for _tty in /dev/pts/*; do ./ttyecho -n 'hash -r' $_tty; done
Since some comments asked for a way to reproduce the issue, I've included the following script to illustrate how hashing can affect which program is executed.
# Create two bin directories
mkdir -p ~/local/bin1
mkdir -p ~/local/bin2
# Add the directories to the PATH, with bin2 preceding bin1
export PATH="$HOME/local/bin2:$HOME/local/bin1:$PATH"
# Create a test script and put it in the bin1 directory
cat <<HEREDOC > ~/local/bin1/test.sh
#!/bin/bash
# test.sh
echo "This is test #1, it's in ~/local/bin1"
HEREDOC
# Make the script executable
chmod +x ~/local/bin1/test.sh
# Verify that the script is found by using the "which" command
which test.sh
# Output:
#
# /home/username/local/bin1/test.sh
# Verify that the script is found by using the "type" command
type test.sh
# Output:
#
# test.sh is /home/username/local/bin1/test.sh
# Test the script
test.sh
# Output:
#
# This is test #1, it's in ~/local/bin1
# Now hash the test script
hash test.sh
# Verify that the script has been hashed by using the "type" command
type test.sh
# Output:
#
# test.sh is hashed (/home/username/local/bin1/test.sh)
# Now create a second test script and put it in bin2 to shadow the first
cat <<HEREDOC > ~/local/bin2/test.sh
#!/bin/bash
# test.sh
echo "This is test #2, it's in ~/local/bin2"
HEREDOC
# Make the second test script executable
chmod +x ~/local/bin2/test.sh
# Verify that the bin2 test script take priority over the bin1 test script
which -a test.sh
# Output:
#
# /home/username/local/bin2/test.sh
# /home/username/local/bin1/test.sh
which test.sh
# Output:
#
# /home/username/local/bin2/test.sh
# Try to run the test script
test.sh
# Ouput:
#
# This is test #1, it's in ~/local/bin1
# NOTE: Even though bin2/test.sh comes before bin1/test.sh in the PATH,
# it's bin1/test.sh that is executed. What's going on?
# Use the "type" command to see which script is being executed
type test.sh
# Output
#
# test.sh is hashed (/home/username/local/bin1/test.sh)
# NOTE: That explains the seeming contradiction.
# Clear the hashed command
hash -d test.sh
# Check that the hashed command has been cleared
type test.sh
# Output:
#
# test.sh is /home/username/local/bin2/test.sh
# Run the test.sh command
test.sh
# Output:
#
# This is test #2, it's in ~/local/bin2
I also found an alternative approach described elsewhere on this site:
- Disable bash's cache of executables in the path
The solution there was to use the PROMPT_COMMAND
variable to continuously clear the path cache, e.g. by adding the following line to your ~/.bashrc
:
PROMPT_COMMAND='hash -r'
Note that this will only affect new sessions and not your pre-existing sessions unless you also execute that command in those sessions.
Finally, you may want to consider using a terminal multiplexer such as tmux. Here is a relevant post from this site:
- Run command in multiple active shells simultaneously
1
How do you knowttyecho
is writing to a prompt thatâÂÂs waiting for a command? Say you have an IRC client in one terminal, an editor in another, and a shell with a complex command youâÂÂre working on (thatâÂÂs supposed to delete a bunch of files, for added fun)...
â Stephen Kitt
Oct 18 '17 at 15:16
@StephenKitt Is this a rhetorical question? If so, I should say that I don't think that this is a good idea. But it sounds like what the question was asking for, no? Personally I don't consider having to runhash -d
a few times to be much of an inconvenience.
â igal
Oct 18 '17 at 15:31
@StephenKitt I added an alternative solution (or approximate solution) that doesn't involve injecting commands into active sessions.
â igal
Oct 18 '17 at 15:42
1
No, itâÂÂs not a rhetorical question. ItâÂÂs an interesting approach, but it does have significant drawbacks, especially for someone like the OP with a bunch of long-lived shells lying around. You end up sending text strings to all terminals, not just âÂÂprogrammatically execut[ing] commands in other active shell sessionsâÂÂ. I would recommend adding the fact that you donâÂÂt think this is a good idea to the answer itself...
â Stephen Kitt
Oct 18 '17 at 15:43
@StephenKitt I completely agree. I've added a cautionary note, per your suggestion.
â igal
Oct 18 '17 at 15:56
add a comment |Â
up vote
0
down vote
Here is the TLDR solution: if you want to programmatically execute commands in pre-existing shell sessions then you can use the ttyecho
program.
WARNING: Note that this is not in general a safe operation and is sensitive to the state of each session. As user StephenKitt points out, this approach requires that each terminal session have a prompt that is waiting to receive input.
An alternative solution would be to effectively disable path-hashing by adding the PROMPT_COMMAND='hash -r'
statement to your ~/.bashrc
file. This won't affect currently running sessions, but will prevent this issue from arising in the future.
Finally, you could consider using a terminal multiplexer such as tmux, which supports executing commands in multiple terminals simultaneously.
A more detailed response follows.
It seems to me that the basic functionality that you're looking for is the ability to programmatically execute commands in other active shell sessions. I found that this question (of how to execute commands in other shell sessions) has been addressed elsewhere on this site, e.g.:
How do I run a command in a different tty?
Execute command in remote active terminal
It seems that the easiest way to execute commands in other active shell sessions is to use the ttyecho
utility. The ttyecho
program is a small, self-contained, single-file C program. Here are a couple of references to the ttyecho
source-code and documentation:
http://www.humbug.in/2010/utility-to-send-commands-or-data-to-other-terminals-ttypts/
https://github.com/osospeed/ttyecho
For completeness, here is the source code:
// ttyecho.c
// Original author: Pratik Sinha
// http://www.humbug.in/2010/utility-to-send-commands-or-data-to-other-terminals-ttypts/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <string.h>
#include <unistd.h>
void print_help(char *prog_name)
printf("Usage: %s [-n] DEVNAME COMMANDn", prog_name);
printf("Usage: '-n' is an optional argument if you want to push a new line at the end of the textn");
printf("Usage: Will require 'sudo' to run if the executable is not setuid rootn");
exit(1);
int main (int argc, char *argv)
char *cmd, *nl = "n";
int i, fd;
int devno, commandno, newline;
int mem_len;
devno = 1; commandno = 2; newline = 0;
if (argc < 3)
print_help(argv[0]);
if (argc > 3 && argv[1][0] == '-' && argv[1][1] == 'n')
devno = 2; commandno = 3; newline=1;
else if (argc > 3 && argv[1][0] == '-' && argv[1][1] != 'n')
printf("Invalid Optionn");
print_help(argv[0]);
fd = open(argv[devno],O_RDWR);
if(fd == -1)
perror("open DEVICE");
exit(1);
mem_len = 0;
for ( i = commandno; i < argc; i++ )
mem_len += strlen(argv[i]) + 2;
if ( i > commandno )
cmd = (char *)realloc((void *)cmd, mem_len);
else //i == commandno
cmd = (char *)malloc(mem_len);
strcat(cmd, argv[i]);
// strcat(cmd, " ");
if (newline == 0)
usleep(225000);
for (i = 0; cmd[i]; i++)
ioctl (fd, TIOCSTI, cmd+i);
if (newline == 1)
ioctl (fd, TIOCSTI, nl);
close(fd);
free((void *)cmd);
exit (0);
If you download the source code or copy-paste it to a file named ttyecho.c
, then you should be able to compile the program like so:
gcc ttyecho.c -o ttyecho
Once the program is compiled you should be able to use it to run any command you'd like in anther shell session. This included being able to programmatically run the hash -r
command in every active shell session. Here is one way to clear the hashed commands on all of the shell sessions on Mac OS X:
for _tty in /dev/ttys*; do ./ttyecho -n 'hash -r' $_tty; done
On a Linux machine you would do something like this instead:
for _tty in /dev/pts/*; do ./ttyecho -n 'hash -r' $_tty; done
Since some comments asked for a way to reproduce the issue, I've included the following script to illustrate how hashing can affect which program is executed.
# Create two bin directories
mkdir -p ~/local/bin1
mkdir -p ~/local/bin2
# Add the directories to the PATH, with bin2 preceding bin1
export PATH="$HOME/local/bin2:$HOME/local/bin1:$PATH"
# Create a test script and put it in the bin1 directory
cat <<HEREDOC > ~/local/bin1/test.sh
#!/bin/bash
# test.sh
echo "This is test #1, it's in ~/local/bin1"
HEREDOC
# Make the script executable
chmod +x ~/local/bin1/test.sh
# Verify that the script is found by using the "which" command
which test.sh
# Output:
#
# /home/username/local/bin1/test.sh
# Verify that the script is found by using the "type" command
type test.sh
# Output:
#
# test.sh is /home/username/local/bin1/test.sh
# Test the script
test.sh
# Output:
#
# This is test #1, it's in ~/local/bin1
# Now hash the test script
hash test.sh
# Verify that the script has been hashed by using the "type" command
type test.sh
# Output:
#
# test.sh is hashed (/home/username/local/bin1/test.sh)
# Now create a second test script and put it in bin2 to shadow the first
cat <<HEREDOC > ~/local/bin2/test.sh
#!/bin/bash
# test.sh
echo "This is test #2, it's in ~/local/bin2"
HEREDOC
# Make the second test script executable
chmod +x ~/local/bin2/test.sh
# Verify that the bin2 test script take priority over the bin1 test script
which -a test.sh
# Output:
#
# /home/username/local/bin2/test.sh
# /home/username/local/bin1/test.sh
which test.sh
# Output:
#
# /home/username/local/bin2/test.sh
# Try to run the test script
test.sh
# Ouput:
#
# This is test #1, it's in ~/local/bin1
# NOTE: Even though bin2/test.sh comes before bin1/test.sh in the PATH,
# it's bin1/test.sh that is executed. What's going on?
# Use the "type" command to see which script is being executed
type test.sh
# Output
#
# test.sh is hashed (/home/username/local/bin1/test.sh)
# NOTE: That explains the seeming contradiction.
# Clear the hashed command
hash -d test.sh
# Check that the hashed command has been cleared
type test.sh
# Output:
#
# test.sh is /home/username/local/bin2/test.sh
# Run the test.sh command
test.sh
# Output:
#
# This is test #2, it's in ~/local/bin2
I also found an alternative approach described elsewhere on this site:
- Disable bash's cache of executables in the path
The solution there was to use the PROMPT_COMMAND
variable to continuously clear the path cache, e.g. by adding the following line to your ~/.bashrc
:
PROMPT_COMMAND='hash -r'
Note that this will only affect new sessions and not your pre-existing sessions unless you also execute that command in those sessions.
Finally, you may want to consider using a terminal multiplexer such as tmux. Here is a relevant post from this site:
- Run command in multiple active shells simultaneously
1
How do you knowttyecho
is writing to a prompt thatâÂÂs waiting for a command? Say you have an IRC client in one terminal, an editor in another, and a shell with a complex command youâÂÂre working on (thatâÂÂs supposed to delete a bunch of files, for added fun)...
â Stephen Kitt
Oct 18 '17 at 15:16
@StephenKitt Is this a rhetorical question? If so, I should say that I don't think that this is a good idea. But it sounds like what the question was asking for, no? Personally I don't consider having to runhash -d
a few times to be much of an inconvenience.
â igal
Oct 18 '17 at 15:31
@StephenKitt I added an alternative solution (or approximate solution) that doesn't involve injecting commands into active sessions.
â igal
Oct 18 '17 at 15:42
1
No, itâÂÂs not a rhetorical question. ItâÂÂs an interesting approach, but it does have significant drawbacks, especially for someone like the OP with a bunch of long-lived shells lying around. You end up sending text strings to all terminals, not just âÂÂprogrammatically execut[ing] commands in other active shell sessionsâÂÂ. I would recommend adding the fact that you donâÂÂt think this is a good idea to the answer itself...
â Stephen Kitt
Oct 18 '17 at 15:43
@StephenKitt I completely agree. I've added a cautionary note, per your suggestion.
â igal
Oct 18 '17 at 15:56
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Here is the TLDR solution: if you want to programmatically execute commands in pre-existing shell sessions then you can use the ttyecho
program.
WARNING: Note that this is not in general a safe operation and is sensitive to the state of each session. As user StephenKitt points out, this approach requires that each terminal session have a prompt that is waiting to receive input.
An alternative solution would be to effectively disable path-hashing by adding the PROMPT_COMMAND='hash -r'
statement to your ~/.bashrc
file. This won't affect currently running sessions, but will prevent this issue from arising in the future.
Finally, you could consider using a terminal multiplexer such as tmux, which supports executing commands in multiple terminals simultaneously.
A more detailed response follows.
It seems to me that the basic functionality that you're looking for is the ability to programmatically execute commands in other active shell sessions. I found that this question (of how to execute commands in other shell sessions) has been addressed elsewhere on this site, e.g.:
How do I run a command in a different tty?
Execute command in remote active terminal
It seems that the easiest way to execute commands in other active shell sessions is to use the ttyecho
utility. The ttyecho
program is a small, self-contained, single-file C program. Here are a couple of references to the ttyecho
source-code and documentation:
http://www.humbug.in/2010/utility-to-send-commands-or-data-to-other-terminals-ttypts/
https://github.com/osospeed/ttyecho
For completeness, here is the source code:
// ttyecho.c
// Original author: Pratik Sinha
// http://www.humbug.in/2010/utility-to-send-commands-or-data-to-other-terminals-ttypts/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <string.h>
#include <unistd.h>
void print_help(char *prog_name)
printf("Usage: %s [-n] DEVNAME COMMANDn", prog_name);
printf("Usage: '-n' is an optional argument if you want to push a new line at the end of the textn");
printf("Usage: Will require 'sudo' to run if the executable is not setuid rootn");
exit(1);
int main (int argc, char *argv)
char *cmd, *nl = "n";
int i, fd;
int devno, commandno, newline;
int mem_len;
devno = 1; commandno = 2; newline = 0;
if (argc < 3)
print_help(argv[0]);
if (argc > 3 && argv[1][0] == '-' && argv[1][1] == 'n')
devno = 2; commandno = 3; newline=1;
else if (argc > 3 && argv[1][0] == '-' && argv[1][1] != 'n')
printf("Invalid Optionn");
print_help(argv[0]);
fd = open(argv[devno],O_RDWR);
if(fd == -1)
perror("open DEVICE");
exit(1);
mem_len = 0;
for ( i = commandno; i < argc; i++ )
mem_len += strlen(argv[i]) + 2;
if ( i > commandno )
cmd = (char *)realloc((void *)cmd, mem_len);
else //i == commandno
cmd = (char *)malloc(mem_len);
strcat(cmd, argv[i]);
// strcat(cmd, " ");
if (newline == 0)
usleep(225000);
for (i = 0; cmd[i]; i++)
ioctl (fd, TIOCSTI, cmd+i);
if (newline == 1)
ioctl (fd, TIOCSTI, nl);
close(fd);
free((void *)cmd);
exit (0);
If you download the source code or copy-paste it to a file named ttyecho.c
, then you should be able to compile the program like so:
gcc ttyecho.c -o ttyecho
Once the program is compiled you should be able to use it to run any command you'd like in anther shell session. This included being able to programmatically run the hash -r
command in every active shell session. Here is one way to clear the hashed commands on all of the shell sessions on Mac OS X:
for _tty in /dev/ttys*; do ./ttyecho -n 'hash -r' $_tty; done
On a Linux machine you would do something like this instead:
for _tty in /dev/pts/*; do ./ttyecho -n 'hash -r' $_tty; done
Since some comments asked for a way to reproduce the issue, I've included the following script to illustrate how hashing can affect which program is executed.
# Create two bin directories
mkdir -p ~/local/bin1
mkdir -p ~/local/bin2
# Add the directories to the PATH, with bin2 preceding bin1
export PATH="$HOME/local/bin2:$HOME/local/bin1:$PATH"
# Create a test script and put it in the bin1 directory
cat <<HEREDOC > ~/local/bin1/test.sh
#!/bin/bash
# test.sh
echo "This is test #1, it's in ~/local/bin1"
HEREDOC
# Make the script executable
chmod +x ~/local/bin1/test.sh
# Verify that the script is found by using the "which" command
which test.sh
# Output:
#
# /home/username/local/bin1/test.sh
# Verify that the script is found by using the "type" command
type test.sh
# Output:
#
# test.sh is /home/username/local/bin1/test.sh
# Test the script
test.sh
# Output:
#
# This is test #1, it's in ~/local/bin1
# Now hash the test script
hash test.sh
# Verify that the script has been hashed by using the "type" command
type test.sh
# Output:
#
# test.sh is hashed (/home/username/local/bin1/test.sh)
# Now create a second test script and put it in bin2 to shadow the first
cat <<HEREDOC > ~/local/bin2/test.sh
#!/bin/bash
# test.sh
echo "This is test #2, it's in ~/local/bin2"
HEREDOC
# Make the second test script executable
chmod +x ~/local/bin2/test.sh
# Verify that the bin2 test script take priority over the bin1 test script
which -a test.sh
# Output:
#
# /home/username/local/bin2/test.sh
# /home/username/local/bin1/test.sh
which test.sh
# Output:
#
# /home/username/local/bin2/test.sh
# Try to run the test script
test.sh
# Ouput:
#
# This is test #1, it's in ~/local/bin1
# NOTE: Even though bin2/test.sh comes before bin1/test.sh in the PATH,
# it's bin1/test.sh that is executed. What's going on?
# Use the "type" command to see which script is being executed
type test.sh
# Output
#
# test.sh is hashed (/home/username/local/bin1/test.sh)
# NOTE: That explains the seeming contradiction.
# Clear the hashed command
hash -d test.sh
# Check that the hashed command has been cleared
type test.sh
# Output:
#
# test.sh is /home/username/local/bin2/test.sh
# Run the test.sh command
test.sh
# Output:
#
# This is test #2, it's in ~/local/bin2
I also found an alternative approach described elsewhere on this site:
- Disable bash's cache of executables in the path
The solution there was to use the PROMPT_COMMAND
variable to continuously clear the path cache, e.g. by adding the following line to your ~/.bashrc
:
PROMPT_COMMAND='hash -r'
Note that this will only affect new sessions and not your pre-existing sessions unless you also execute that command in those sessions.
Finally, you may want to consider using a terminal multiplexer such as tmux. Here is a relevant post from this site:
- Run command in multiple active shells simultaneously
Here is the TLDR solution: if you want to programmatically execute commands in pre-existing shell sessions then you can use the ttyecho
program.
WARNING: Note that this is not in general a safe operation and is sensitive to the state of each session. As user StephenKitt points out, this approach requires that each terminal session have a prompt that is waiting to receive input.
An alternative solution would be to effectively disable path-hashing by adding the PROMPT_COMMAND='hash -r'
statement to your ~/.bashrc
file. This won't affect currently running sessions, but will prevent this issue from arising in the future.
Finally, you could consider using a terminal multiplexer such as tmux, which supports executing commands in multiple terminals simultaneously.
A more detailed response follows.
It seems to me that the basic functionality that you're looking for is the ability to programmatically execute commands in other active shell sessions. I found that this question (of how to execute commands in other shell sessions) has been addressed elsewhere on this site, e.g.:
How do I run a command in a different tty?
Execute command in remote active terminal
It seems that the easiest way to execute commands in other active shell sessions is to use the ttyecho
utility. The ttyecho
program is a small, self-contained, single-file C program. Here are a couple of references to the ttyecho
source-code and documentation:
http://www.humbug.in/2010/utility-to-send-commands-or-data-to-other-terminals-ttypts/
https://github.com/osospeed/ttyecho
For completeness, here is the source code:
// ttyecho.c
// Original author: Pratik Sinha
// http://www.humbug.in/2010/utility-to-send-commands-or-data-to-other-terminals-ttypts/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <string.h>
#include <unistd.h>
void print_help(char *prog_name)
printf("Usage: %s [-n] DEVNAME COMMANDn", prog_name);
printf("Usage: '-n' is an optional argument if you want to push a new line at the end of the textn");
printf("Usage: Will require 'sudo' to run if the executable is not setuid rootn");
exit(1);
int main (int argc, char *argv)
char *cmd, *nl = "n";
int i, fd;
int devno, commandno, newline;
int mem_len;
devno = 1; commandno = 2; newline = 0;
if (argc < 3)
print_help(argv[0]);
if (argc > 3 && argv[1][0] == '-' && argv[1][1] == 'n')
devno = 2; commandno = 3; newline=1;
else if (argc > 3 && argv[1][0] == '-' && argv[1][1] != 'n')
printf("Invalid Optionn");
print_help(argv[0]);
fd = open(argv[devno],O_RDWR);
if(fd == -1)
perror("open DEVICE");
exit(1);
mem_len = 0;
for ( i = commandno; i < argc; i++ )
mem_len += strlen(argv[i]) + 2;
if ( i > commandno )
cmd = (char *)realloc((void *)cmd, mem_len);
else //i == commandno
cmd = (char *)malloc(mem_len);
strcat(cmd, argv[i]);
// strcat(cmd, " ");
if (newline == 0)
usleep(225000);
for (i = 0; cmd[i]; i++)
ioctl (fd, TIOCSTI, cmd+i);
if (newline == 1)
ioctl (fd, TIOCSTI, nl);
close(fd);
free((void *)cmd);
exit (0);
If you download the source code or copy-paste it to a file named ttyecho.c
, then you should be able to compile the program like so:
gcc ttyecho.c -o ttyecho
Once the program is compiled you should be able to use it to run any command you'd like in anther shell session. This included being able to programmatically run the hash -r
command in every active shell session. Here is one way to clear the hashed commands on all of the shell sessions on Mac OS X:
for _tty in /dev/ttys*; do ./ttyecho -n 'hash -r' $_tty; done
On a Linux machine you would do something like this instead:
for _tty in /dev/pts/*; do ./ttyecho -n 'hash -r' $_tty; done
Since some comments asked for a way to reproduce the issue, I've included the following script to illustrate how hashing can affect which program is executed.
# Create two bin directories
mkdir -p ~/local/bin1
mkdir -p ~/local/bin2
# Add the directories to the PATH, with bin2 preceding bin1
export PATH="$HOME/local/bin2:$HOME/local/bin1:$PATH"
# Create a test script and put it in the bin1 directory
cat <<HEREDOC > ~/local/bin1/test.sh
#!/bin/bash
# test.sh
echo "This is test #1, it's in ~/local/bin1"
HEREDOC
# Make the script executable
chmod +x ~/local/bin1/test.sh
# Verify that the script is found by using the "which" command
which test.sh
# Output:
#
# /home/username/local/bin1/test.sh
# Verify that the script is found by using the "type" command
type test.sh
# Output:
#
# test.sh is /home/username/local/bin1/test.sh
# Test the script
test.sh
# Output:
#
# This is test #1, it's in ~/local/bin1
# Now hash the test script
hash test.sh
# Verify that the script has been hashed by using the "type" command
type test.sh
# Output:
#
# test.sh is hashed (/home/username/local/bin1/test.sh)
# Now create a second test script and put it in bin2 to shadow the first
cat <<HEREDOC > ~/local/bin2/test.sh
#!/bin/bash
# test.sh
echo "This is test #2, it's in ~/local/bin2"
HEREDOC
# Make the second test script executable
chmod +x ~/local/bin2/test.sh
# Verify that the bin2 test script take priority over the bin1 test script
which -a test.sh
# Output:
#
# /home/username/local/bin2/test.sh
# /home/username/local/bin1/test.sh
which test.sh
# Output:
#
# /home/username/local/bin2/test.sh
# Try to run the test script
test.sh
# Ouput:
#
# This is test #1, it's in ~/local/bin1
# NOTE: Even though bin2/test.sh comes before bin1/test.sh in the PATH,
# it's bin1/test.sh that is executed. What's going on?
# Use the "type" command to see which script is being executed
type test.sh
# Output
#
# test.sh is hashed (/home/username/local/bin1/test.sh)
# NOTE: That explains the seeming contradiction.
# Clear the hashed command
hash -d test.sh
# Check that the hashed command has been cleared
type test.sh
# Output:
#
# test.sh is /home/username/local/bin2/test.sh
# Run the test.sh command
test.sh
# Output:
#
# This is test #2, it's in ~/local/bin2
I also found an alternative approach described elsewhere on this site:
- Disable bash's cache of executables in the path
The solution there was to use the PROMPT_COMMAND
variable to continuously clear the path cache, e.g. by adding the following line to your ~/.bashrc
:
PROMPT_COMMAND='hash -r'
Note that this will only affect new sessions and not your pre-existing sessions unless you also execute that command in those sessions.
Finally, you may want to consider using a terminal multiplexer such as tmux. Here is a relevant post from this site:
- Run command in multiple active shells simultaneously
edited Oct 18 '17 at 16:00
answered Oct 16 '17 at 4:27
igal
4,820930
4,820930
1
How do you knowttyecho
is writing to a prompt thatâÂÂs waiting for a command? Say you have an IRC client in one terminal, an editor in another, and a shell with a complex command youâÂÂre working on (thatâÂÂs supposed to delete a bunch of files, for added fun)...
â Stephen Kitt
Oct 18 '17 at 15:16
@StephenKitt Is this a rhetorical question? If so, I should say that I don't think that this is a good idea. But it sounds like what the question was asking for, no? Personally I don't consider having to runhash -d
a few times to be much of an inconvenience.
â igal
Oct 18 '17 at 15:31
@StephenKitt I added an alternative solution (or approximate solution) that doesn't involve injecting commands into active sessions.
â igal
Oct 18 '17 at 15:42
1
No, itâÂÂs not a rhetorical question. ItâÂÂs an interesting approach, but it does have significant drawbacks, especially for someone like the OP with a bunch of long-lived shells lying around. You end up sending text strings to all terminals, not just âÂÂprogrammatically execut[ing] commands in other active shell sessionsâÂÂ. I would recommend adding the fact that you donâÂÂt think this is a good idea to the answer itself...
â Stephen Kitt
Oct 18 '17 at 15:43
@StephenKitt I completely agree. I've added a cautionary note, per your suggestion.
â igal
Oct 18 '17 at 15:56
add a comment |Â
1
How do you knowttyecho
is writing to a prompt thatâÂÂs waiting for a command? Say you have an IRC client in one terminal, an editor in another, and a shell with a complex command youâÂÂre working on (thatâÂÂs supposed to delete a bunch of files, for added fun)...
â Stephen Kitt
Oct 18 '17 at 15:16
@StephenKitt Is this a rhetorical question? If so, I should say that I don't think that this is a good idea. But it sounds like what the question was asking for, no? Personally I don't consider having to runhash -d
a few times to be much of an inconvenience.
â igal
Oct 18 '17 at 15:31
@StephenKitt I added an alternative solution (or approximate solution) that doesn't involve injecting commands into active sessions.
â igal
Oct 18 '17 at 15:42
1
No, itâÂÂs not a rhetorical question. ItâÂÂs an interesting approach, but it does have significant drawbacks, especially for someone like the OP with a bunch of long-lived shells lying around. You end up sending text strings to all terminals, not just âÂÂprogrammatically execut[ing] commands in other active shell sessionsâÂÂ. I would recommend adding the fact that you donâÂÂt think this is a good idea to the answer itself...
â Stephen Kitt
Oct 18 '17 at 15:43
@StephenKitt I completely agree. I've added a cautionary note, per your suggestion.
â igal
Oct 18 '17 at 15:56
1
1
How do you know
ttyecho
is writing to a prompt thatâÂÂs waiting for a command? Say you have an IRC client in one terminal, an editor in another, and a shell with a complex command youâÂÂre working on (thatâÂÂs supposed to delete a bunch of files, for added fun)...â Stephen Kitt
Oct 18 '17 at 15:16
How do you know
ttyecho
is writing to a prompt thatâÂÂs waiting for a command? Say you have an IRC client in one terminal, an editor in another, and a shell with a complex command youâÂÂre working on (thatâÂÂs supposed to delete a bunch of files, for added fun)...â Stephen Kitt
Oct 18 '17 at 15:16
@StephenKitt Is this a rhetorical question? If so, I should say that I don't think that this is a good idea. But it sounds like what the question was asking for, no? Personally I don't consider having to run
hash -d
a few times to be much of an inconvenience.â igal
Oct 18 '17 at 15:31
@StephenKitt Is this a rhetorical question? If so, I should say that I don't think that this is a good idea. But it sounds like what the question was asking for, no? Personally I don't consider having to run
hash -d
a few times to be much of an inconvenience.â igal
Oct 18 '17 at 15:31
@StephenKitt I added an alternative solution (or approximate solution) that doesn't involve injecting commands into active sessions.
â igal
Oct 18 '17 at 15:42
@StephenKitt I added an alternative solution (or approximate solution) that doesn't involve injecting commands into active sessions.
â igal
Oct 18 '17 at 15:42
1
1
No, itâÂÂs not a rhetorical question. ItâÂÂs an interesting approach, but it does have significant drawbacks, especially for someone like the OP with a bunch of long-lived shells lying around. You end up sending text strings to all terminals, not just âÂÂprogrammatically execut[ing] commands in other active shell sessionsâÂÂ. I would recommend adding the fact that you donâÂÂt think this is a good idea to the answer itself...
â Stephen Kitt
Oct 18 '17 at 15:43
No, itâÂÂs not a rhetorical question. ItâÂÂs an interesting approach, but it does have significant drawbacks, especially for someone like the OP with a bunch of long-lived shells lying around. You end up sending text strings to all terminals, not just âÂÂprogrammatically execut[ing] commands in other active shell sessionsâÂÂ. I would recommend adding the fact that you donâÂÂt think this is a good idea to the answer itself...
â Stephen Kitt
Oct 18 '17 at 15:43
@StephenKitt I completely agree. I've added a cautionary note, per your suggestion.
â igal
Oct 18 '17 at 15:56
@StephenKitt I completely agree. I've added a cautionary note, per your suggestion.
â igal
Oct 18 '17 at 15:56
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f398028%2fhow-to-hash-r-and-refresh-all-shells%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
If you installed a program in one of the $PATH directories, you shouldn't even need to rehash. Curious why you're using -r, as well.
â Jeff Schaller
Oct 13 '17 at 23:59
@Jeff - You certainly need it even when installing on
$PATH
; see, for example, Path not being honored? on OS X stack exchange. As for-r
, I staterted using it to try and get Bash to forget the old version of the program installed in/usr/bin
(re: OS X question). If you have another recommendation, then I'd be happy to use it.â jww
Oct 14 '17 at 0:04
You're replacing an existing $PATH'd binary with a different one of the same name?
â Jeff Schaller
Oct 14 '17 at 0:05
@jeff - Yes. For example, I might be upgrading (displacing?)
emacs
oropenssl
located in/usr/bin
with a new one located in/usr/local/bin
. I never overwrite or delete what's in/usr/bin
. I install something new in/usr/local/bin
.â jww
Oct 14 '17 at 0:07
1
@JeffSchaller I added a pseudo-script at the bottom of my solution which I think produces something like what jww is experiencing.
â igal
Oct 16 '17 at 13:47