3

How is it possible to execute a shell script without creating a file? For example assume I have the following script (testscript):

#!/bin/bash
function run_free() {
   free -m
}

run_free

I then of course can execute this with: sh testscript

I want to ovoid creating a file though. I tried:

sh echo '#!/bin/bash function run_free() { free -m } run_free'

Which did not work. Any ideas?

3
  • 1
    Why would you want to do this - what are you trying to achieve ?
    – user9517
    Jun 21, 2012 at 7:00
  • Its a long story, basically the shell scripts are being passed via SSH, so there is no need to create a file and add +x. I want to simply execute the shell script string.
    – Justin
    Jun 21, 2012 at 7:01
  • Just a note: the issue you identified in your clarification was not the question you asked. In general, state your constraints and your goals. Not your presumed methods (which in this case really don't make much sense). Jun 27, 2012 at 22:47

5 Answers 5

10

Most interpreters have a parameter to specify some code to execute. You can use this to invoke a specific interpreter and provide the code. For example:

bash -c 'function run_free() { free -m; }; run_free'

(Note that you need some semicolons in there since you don't have newlines.)

perl uses -e, and python uses -c.

2

You can use here documents to feed SSH scripts:

ssh -T myhost <<EOF
hostname
whoami
uptime
EOF

The '-T' option disables TTY allocation.

I use this technique to run a standard script across multiple user accounts on one of our 3rd-party services which doesn't allow for a commonly-accessible writable bin directory. The SSH here-document method obviates the need to copy (and maintain) the same script across multiple accounts.

1

Yo dawg, I heard you like shell, so I put shell in your shell so can shell while you shell.

In other words, you are spawning a shell for your echo command and then just echoing everything in one line. Shell interprets that as just an echo command. Even if it did not, the fact that everything is in one line (especially that there is no new line after #!/bin/bash) causes problems.

While typing this reply, I found out from your comment you are going to run commands over ssh. Then something like this should work:

ssh your_user@yourserver "function run_free() { free -m } run_free"
4
  • Don't we need to specify the shebank? What if we wanted to pass a perl script?
    – Justin
    Jun 21, 2012 at 7:05
  • Why didn't you say you wanted to run perl scripts too ?
    – user9517
    Jun 21, 2012 at 7:10
  • @Justin: If you want to run Perl over ssh, just use ssh your_user@yourserver "perl some_script.pl" or ssh your_user@yourserver "perl -e 'your Perl code goes here'". Jun 21, 2012 at 7:44
  • @Justin The shebang is only used in shell scripts, i.e. in files, and is not processed by the shell itself. In fact, the shell ignores it because it is a comment (it starts with '#'). That's the reason why bash -c '#!/bin/bash echo hello' won't output anything: bash ignores the whole command because it is a comment. Jun 21, 2012 at 7:50
0

You could create the scripts on the ssh originating system and pipe them into the ssh session

ssh [email protected] /bin/bash <local.script

Putting your example in a local script run_free

ssh somehost.tld /bin/bash <run_free
Pseudo-terminal will not be allocated because stdin is not a terminal.
         total       used       free     shared    buffers     cached
Mem:           371        246        124          0         49         80
-/+ buffers/cache:        116        254
Swap:          767          0        767

runs the local script on the remote host.

You can do the same thing with perl

ssh [email protected] /usr/bin/perl <perl.script
1
  • Can you send arguments to that script? Aug 4, 2012 at 0:13
0

If I understood question correctly, you were very close, but sh echo '#!/bin/bash input string in the beginning was unnecessary.

I've tried your code in Ubuntu 20.04, bash version 5.0.17. All I've done is just started to print function in terminal:

enter image description here

@mgorven answer is OK, but doesn't allow multi-line code, that can be inconvenient enough, if code lines are long.

You must log in to answer this question.

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