Trying to connect to multiple machines using bash on a machine that has the public ssh keys for the others and run a command on them to display the output on this machine. If I use the '$a' variable as in the code below when I execute the script I get this uncompleted output
bash: total: command not found
bash: line 1: drwxr-xr-x: command not found
bash: line 2: drwxr-xr-x: command not found
bash: line 3: -rw-r--r--: command not found
bash: line 5: -rwxr-xr-x: command not found
....
However if I use the commented block without calling the $a variable the bash prints the correct output of the command.
The code executed:
#!/bin/bash
a=$(ls -lah)
for i in "machine1" "machine2"
do ssh root\#"$i" "$a; exit;"
*#do ssh root\#"$i" "ls -lah; exit;" - displays accordingly*
done
Your code does not work because a=$(ls -lah) assigns ls -lah's output to variable a. Change it to a='ls -lah' and it will be ok.
See command substitution section in your bash's manual
Hi I have another answer which i have been using for a long time.
declare machines=("user#machine1" "user#machine2")
command="ls -lah"
for machine in "${machines[#]}"
do
ssh "$machine" "$command"
done
$a did not work because it will be executed.
Related
This question already has answers here:
Pass commands as input to another command (su, ssh, sh, etc)
(3 answers)
Closed 2 years ago.
I am trying to write a script that sets my main terminal to use bash shell. I know the #!/bin/bash will call all the commands in the script to be run with the bash shell but what I want is a script that specifically that changes the shell of my terminal to bash.
for example: (this is how my terminal looks like when it is opened.)
$
when i want to set the terminal to bash I manually type the bash command and press enter.
$bash
outcome:
[tyg#rooto ~]$
The problem is if I write a script using the above command it works but any command after the bash command in the script fails to execute.
for example
#!/bin/bash
bash
echo "setting terminal environment to bash"
echo "success"
output:
[tyg#rooto ~]$
Expected output: (something like this)
[tyg#rooto ~]$ setting terminal environment to bash
[tyg#rooto ~]$ success
or (Like this)
[tyg#rooto ~]$
[tyg#rooto ~]$ setting environment
[tyg#rooto ~]$ success
any of the above is what I assume should be expected. Why are the two echo commands in the script failing to execute and is there a fix to this. Thanks
#!/bin/bash will invoke the shell in which the subsequent script commands will be executed and upon completion, the shell will be gone. This is how you "execute commands in the changed shell"
bash on line 2 opens a 2nd bash shell in which your echo command is being executed. It too goes away on completion of the script - that's why you don't see the output as expected.
Yes, you can execute a "bash" script in any shell as long as the first line has the correct shell you want.
By removing the bash on line two, you'll see your output.
Example 1
#!/bin/bash
bash << "EOT"
echo "setting environment"
EOT
Example 2
Add this code to a sample script, test.sh, then launch it:
#!/bin/bash
echo "Shell: $$"
bash << "EOT"
echo "Shell: $$"
EOT
echo "Shell: $$"
Result:
Shell: 569 # Current shell
Shell: 570 # Shell in your new enviroment
Shell: 569 # Back to old shell
I have two scripts:
fail_def.sh:
#!/bin/bash -eu
function fail() {
echo -e "$(error "$#")"
exit 1
}
bla.sh:
#!/bin/bash -eu
fail "test"
After source fail_def.sh, I can use the fail command without any problems in the terminal. However, when I call bla.sh, I always get line 2: fail: command not found.
It doesn't matter whether I call it via ./bla.sh or bash bla.sh or bash ./bla.sh, the error remains.
Adding source fail_def.sh to the beginning of bla.sh solves the problem, but I'd like to avoid that.
I'm working on an Ubuntu docker container running on a Mac, in case that is relevant.
I tried to google that problem and found some similar problems, but most of them seem to be connected to either not sourcing the file or mixing up different shell implementations, neither of which seems to be the case here.
What do I have to do to get the fail command to work inside the script?
It is expected!
The shell runs the script run with an she-bang separator always as a separate process and hence on a different shell namespace. The new shell in which your script runs does not have the function source'd.
For debugging such information, add a line echo $BASHPID which prints the process id of the current bash process on the bla.sh script after the line #!/bin/bash -eu and a test result produced
$ echo $BASHPID
11700
$ bash bla.sh
6788
fail.sh: line 3: fail: command not found
They scripts you have run on separate process where the imported functions are not shared between. One of the ways would be to your own error handling on the second script and by source-ing the second script. On the second script
$ cat fail.sh
echo $BASHPID
set -e
fail "test"
set +e
Now running it
$ source fail.sh
11700
11700
bash: error: command not found
which is obvious as error is not a shell built-in which is available. Observe the process id's same on the above case.
I want to run this script:
#!/bin/bash
echo <(true)
I run it as:
sh file.sh
And I get "Syntax error: "(" unexpected" . I found some similar situations but still can't solve this.
I'm a beginner at shell scripting , but as I understand:
the shebang I use is correct and chooses the bash shell , so the process substitution syntax should work
I try the same from the command line and it works. I checked with echo $0 and it gives me "bash" , so what's the difference from running the command in the command line and from a script that invokes the same shell?
Maybe it's something simple, but I couldn't find an explanation or solution.
You should run your script with bash, i.e. either bash ./script.sh or making use of the shebang by ./script.sh after setting it to executable. Only running it with sh ./script.sh do I get your error, as commented by Cyrus.
See also: role of shebang at unix.SE
Remove export POSIXLY_CORRECT=1 from your ~/.bashrc or ~/.profile (etc.) files.
The issue is that process substitution is an added bash feature that is not part of the posix standards.
sh file.sh
errorsh: 3: Syntax error: "(" unexpected
solution:
bash file.sh
#!/bin/bash
tab="--tab"
cmd="bash -c 'python';bash"
foo=""
for i in 1 2 3; do
foo+=($tab -e "$cmd")
done
gnome-terminal "${foo[#]}"
exit 0
i'm using this scirpt to open multiple tabs using shell script.
call it multitab.sh and execute this way user#user:~$ sh multitab.sh
currently this script supposed to open 3 tabs and all of them will execute python command.
but when i execute it, throws en error
multitab.sh: 8: multitab.sh: Syntax error: word unexpected (expecting ")")
What is the reason of this error? How can I make this script to execute 3 different commands?
I've already gone through. below SOF threads but none of them worked for me.
https://askubuntu.com/questions/315408/open-terminal-with-multiple-tabs-and-execute-application
https://askubuntu.com/questions/500357/opening-multiple-terminal-tabs-and-running-command
https://askubuntu.com/questions/521084/bash-script-for-multiple-tabs-program-running
This is because you are running the script with sh, where the += syntax to add elements is not available:
foo+=($tab -e "$cmd")
# ^^
So all you need to do is to run the script with Bash:
bash multitab.sh
Or just using ./multitab.sh (after giving executing mode to the file), since the shebang in the script (#!/bin/bash) already mentions Bash.
From the Bash Reference Manual:
Appendix B Major Differences From The Bourne Shell
- Bash supports the ‘+=’ assignment operator, which appends to the value of the variable named on the left hand side.
I trying to create a .sh file that execute things like "pwd" or "ls" command.
My problem its when i execute the .sh file.
Its seems not recognize the tasks
I tried to use echo
Example : echo 'lsApps' or echo "lsApps"
but it prints the name of the task instead execute the comand
for example i want to execute a .ssh file that makes a pwd
VAR_1=pwd
echo $VAR_1
but it prints me pwd instead the current path ...
Any idea?
echo is used to print on the screen (man page reference). If you do echo 'IsApps' it will take it as a string and print it. If you want to execute a command you can just do it by doing IsApps (acutes not quotes, acute is usually below the escape key). This will execute the command and show the output on the screen. If you want to store the output of the command in a variable, you can do
<variable_name>=`IsApps`
This will store the output in the variable. Note that there is no space between variable name and the command. Also, those are not quotes but instead acutes. To print the variable on screen you can use echo by doing echo $<variable_name>
If you don't want to see the output at all. You can do
IsApps > /dev/null
this will execute the command but you will not see any stdout on your screen.
As far as ssh is concerned, do ssh-keygen and then ssh-copy-id user#remote_ip to set ssh keys so that you don't have to enter your password with ssh. Once you have done that, you can use ssh user#remote_ip in your shell script.