How to 'hash -r' and refresh all shells?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
3
down vote

favorite
2












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.






share|improve this question






















  • 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 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




    @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














up vote
3
down vote

favorite
2












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.






share|improve this question






















  • 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 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




    @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












up vote
3
down vote

favorite
2









up vote
3
down vote

favorite
2






2





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.






share|improve this question














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.








share|improve this question













share|improve this question




share|improve this question








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 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




    @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










  • @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 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




    @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










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





share|improve this answer


















  • 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










  • @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






  • 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










Your Answer







StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















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






























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





share|improve this answer


















  • 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










  • @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






  • 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














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





share|improve this answer


















  • 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










  • @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






  • 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












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





share|improve this answer














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






share|improve this answer














share|improve this answer



share|improve this answer








edited Oct 18 '17 at 16:00

























answered Oct 16 '17 at 4:27









igal

4,820930




4,820930







  • 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










  • @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






  • 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




    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 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

















 

draft saved


draft discarded















































 


draft saved


draft discarded














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













































































Popular posts from this blog

How to check contact read email or not when send email to Individual?

Displaying single band from multi-band raster using QGIS

How many registers does an x86_64 CPU actually have?