2

Is there a way to have a shell script output text at the command prompt WITHOUT issuing the command?

CONTEXT: I SSH into a particular machine several times a day, and about 80% of the time, I type the same three commands as soon as I login. I would just put these commands in my .bashrc, but 20% of the time, I do NOT want to issue these commands. I'm wondering if there is some command I can put in .bashrc that will automatically put a string at my command line, so that when I login I see:

$ cd some/dir && ./some_script.sh

I could then just press enter 80% of the time or just clear the text the other 20% of the time.

4
  • Is there a reason you need to log in to enter the commands? Would ssh user@somehost "cd some/dir && ./some_script.sh" from your local computer work just as well? Commented Oct 22, 2015 at 17:20
  • That's a good idea, but yeah, I do usually want to actually login to the machine as well. Commented Oct 22, 2015 at 17:23
  • I would use expect for this, but that's just me. Commented Oct 22, 2015 at 18:02
  • For what it's worth, the print command in zsh can do this: print -z 'cd some/dir && ./some_script.sh'. I don't think there is a way to execute arbitrary readline commands (the relevant ones being start-kbd-macro, end-kbd-macro, and call-last-kbd-macro). Commented Oct 22, 2015 at 18:08

6 Answers 6

7

(Inspired by Abdul Rehman's answer.)

Put this as the last line in your .bashrc file:

read -e -p "(Control-C to cancel) $ " -i "cd some/dir && ./some_script.sh" && eval "$REPLY"
  • read -e lets you enter a string using Readline for editing.
  • The -p provides a pseudo-prompt for this one-time command.
  • The -i provides a default string which you can edit or hit Enter to accept.

If you hit Enter, read sets the value of REPLY and exits with status 0, causing the following eval to execute. (Usually, eval is not a good command to use; however, here you would be presented with an interactive shell anyway, so there's not much risk here.) If you type Control-C instead, read exits with status 1 and the following eval is not executed, leaving you at your command prompt.

Sign up to request clarification or add additional context in comments.

1 Comment

Props to all the answers, in particular @shanmuga 's single-character alias. However, this answer came closest to what I originally asked for in that one keystroke allows me to run the command or cancel immediately upon login.
6

I know this is not what you asked but why don't use alias to shorten your command?

$ alias a='cd some/dir && ./some_script.sh'

Since you are going to use this often you could add this to you .bashrc file, so you don't have to set the alias every time.
After login you could just type a

$ a

1 Comment

And put the first line in the .bashrc. After login you only need to type a (and Enter).
4

I don't know of a way to do that but you could use history -s to push that command/those commands into the history when you log in which would then let you use !!<cr> or <up><cr> to execute them and just proceed normally if you don't.

history -s cd some/dir '&&' ./some_script.sh

You need to quote anything that the shell would normally evaluate/expand/remove. So the && in that example, any quotes, any semicolons, etc.

6 Comments

This works well as is a big improvement for me (esp. since the real command I want to enter is more complicated). +1 but leaving unchecked for now since I'm curious to see if there's a way to do my initial idea.
I think you probably meant that someone could hit <esc>k<cr> to run the command, because who would use emacs mode? ;)
@dannysauer People who realize that the shell doesn't have a meaningful "normal mode" since you aren't editing a document and don't generally need to move very far. =)
I used to think so, but now I can't stand having to hit the arrow keys more than twice. :) Don't ever switch over to vi mode; it's impossible to go back.
@dannysauer Why would you use the arrow keys in emacs mode anyway? The modified jumping keys are much more useful. ctrl-p for up, alt-b/alt-f for word-jumping, etc.
|
4

Put this script in .bashrc. It will ask you to run this command.

while true; do
read -p "Run this command?" yn
case $yn in
    [Yy]* ) cd some/dir && ./some_script.sh; break;;
    [Nn]* ) break;;
    * ) echo "Enter Yes or No."
esac
done

Comments

2

I know it's been more than 9 years, but for anyone who stumbled upon this question while searching:

Yes you can, the way depends on your shell (so check its manual first), i.g. ZSH supports it natively with print -z [args] pushing the arguments onto the editing buffer stack, separated by spaces (check the docs). While other shells don't, i.g. BASH. So you need to hack your way. I'd assume you're using BASH.

You need to use read with readline(3), $PS1 as the prompt (not necessary, just aesthetics) and place your desired command in the editing buffer, then execute it. Thus:

read -e -p "${PS1@P}" -i "[COMMAND]" cmd; bash -c "$cmd"

To understand the command refer to read's section in the BASH manual.

There's multiples ways of executing this idea, and they may differentiate based on the shell used, so don't take anything literally, and prioritize your shell's documentation above all.

PS: For better experience, you can enable vi mode in readline by appending set editing-mode vi in ~/.inputrc, and more.

Comments

0

You can run script on remote server instead loggin via ssh:

ssh <SERVER> some/dir/some_script.sh

For the remaining 20% you can connect ssh as usual.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.