Running .ksh Scripts from Solaris KornShell - shell

I have developed a few KornShell (ksh) scripts to run on Solaris. I run the scripts over Putty. On one server, I am able to run them as follows:
$ script.ksh
On the other, server, I need to run them as follows:
$ ./script.ksh
Otherwise I get a script.ksh not found error. What would cause this difference? I call scripts from within this script, and do not want to have to change all the scripts to append './' to each script invocation in order to get the scripts working.
Both servers uname -a reports following:
$ uname -a = SunOS servername 5.10 Generic_147440-10 sun4u sparc SUNW,Sun-Fire-V245
$ echo $SHELL = /bin/ksh

Add PATH="$PATH:." to the main script.

Related

Running Linux Shell on AIX

I tried to execute a shell script on AIX and it failed because some declaration/instructions (like readarray, array declaration, date command with specific args etc) from shell is not recognized in ksh
I would like to execute this linux script on AIX without rewrite the entire script in ksh.
I tried to run the script using different shebang like #!/usr/bin/env bash or #!/bin/sh but AIX seems still running it through ksh.
Would someone have a solution to run linux shell on AIX ?
« AIX Toolbox for Linux Applications » seems provide to execute linux shell on AIX.
Could someone confirm me this information ?
How can I check if AIX Toolbox is already install on the AIX server ? (i don’t have the administration right on this server)
How to execute AIX Toolbox to run shell script ?
Thanks in advance for your help
As you can see from the link you can install AIX Toolbox for Linux Applications and you will have bash. Also you can download only this package and install it.
After install you can exec bash as any other program in your OS.
But in generally you can reach a lot of challenges when try to run linux script on AIX or HP-UX.
You can use bash! Need to install yum from here. Once yum is installed it will auto-install bash package.
Put in a temporary empty folder, untar it and install all RPMs: rpm -Uvh *.rpm.
Edit /etc/security/login.cfg anb and "/usr/bin/bash" in the end:
shells = /bin/sh,/bin/bsh,/bin/csh,/bin/ksh,/bin/tsh,/bin/ksh93,/usr/bin
/sh,/usr/bin/bsh,/usr/bin/csh,/usr/bin/ksh,/usr/bin/tsh,/usr/bin/ksh93,/usr/bin/
rksh,/usr/bin/rksh93,/usr/sbin/uucp/uucico,/usr/sbin/sliplogin,/usr/sbin/snappd,
/usr/bin/bash
Add path /usr/bin/bash to /etc/shells:
# echo “/usr/bin/bash” >> /etc/shells
Change shell to se bash:
# chuser shell=/usr/bin/bash root
Create a new .bash_profile inside root's home with:
# .bash_profile
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
PS1="[\u#\h \w]\$ "
export PS1
Login with root and you see something like this:
[root#aixserver ~]#

Running a file on remote server by ssh respecting shebang line

So I have a file. Currently it looks like this:
#!/usr/bin/env python3
print(1)
I want to tun it on remote machine. The easy way to do this is to run
< test.py ssh server-name python3
But what if I don't know that it's a python script (or I may not know that it's python3 not python2) and want to respect its shebang?
I tried
< test.py ssh server-name exec /dev/stdin
But it fails since /dev/stdin is not executable
For simplicity let's assume both of the servers are latest Ubuntu.
So the question is how to run arbitrary script respecting it shebang?
It's the OS that uses the shebang line: see your execve(2) man page. The script file must be executable, residing on the system.
You can extract it from the script to use on the remote side: untested:
shebang=$(sed -n '1 {s/^#!//p; q}' test.py)
ssh server-name "$shebang -" < test.py

bash how to pass variable to the remote bash script

I have local bash script which is used to invoke a bash script in the remote server and get some reports from remote server.
The way I call this script currently in local_script.sh is:
ssh remoteuse#ip "/bin/bash remote_script.sh"
Now, I want to set a date variable in local_script.sh file and variable needs to available in remote_script.sh files also.
Please give some ideas.
EDIT:
Please see my test script:
[user#localserver]$ ssh remoteusr#ip "/bin/bash remote_script.sh $test_var"
And my remote script:
[user#remoteserver]$ cat remote_script.sh
#!/bin/bash
echo $test_var > test_var.log
But test_var.log file on remote server is empty after running the script
The remote server doesn't know you local variables, you can only pass the value of the variable from local to remote with an extra argument at the ssh line:
ssh remoteuse#ip "/bin/bash remote_script.sh $variable"
You have to add the variable to the environment of the executed command. That can be done with the var=value cmd syntax.
But since the line you pass to ssh will be evaluated on the remote server, you must ensure the variable is in a format that is reusable as shell input. Two ways come to mind depending on your version of bash:
With bash 4.4 or newer, you can use the Q operator in ${parameter#operator}:
local script:
foo="abc'def \"123\" *"
ssh remoteuse#ip "foo=${foo#Q} /bin/bash remote.sh"
remote script:
printf '<%s>\n' "$foo"
output:
$ ./local_script.sh
<abc'def "123" *>
If you don't have bash 4.4 or newer, you can use the %q directive to printf:
ssh remoteuse#ip "foo=$(printf '%q' "$foo") /bin/bash remote.sh"

Eval in docker-machine: terminal vs shell script

I'm trying to run a simple shell script to automate changing docker-machine environments. The problem is this, when I run the following command directly in the Mac terminal the following is outputted:
eval $(docker-machine env default)
docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
default * digitalocean Running tcp://***.**.***.***:**** v1.12.0
So basically what you would expect, however when I run the following .sh script:
#!/usr/bin/env bash
eval $(docker-machine env default)
The output is:
./run.sh
docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
default digitalocean Running tcp://***.**.***.***:**** v1.12.0
So basically, it is not setting it as active and I cannot access it.
Has anyone run into this issue before and knows how to solve it? Seems really strange to me, have got pretty much everything else running and automated apart from this facet.
Cheers, Aaron
I think you need to source your shell script
source ./myscript.sh
as the exports in the eval are being returned to the process you started to run the shell in and then being disposed of. These need to go to the parent e.g. login shell
Consider a.sh
#!/bin/bash
eval $(echo 'export a=123')
export b=234
when run in two ways
$ ./a.sh
$ echo $a
$ echo $b
$ source a.sh
$ echo $a
123
$ echo $b
234
$

sh: ...: is not an identifier when trying to invoke shell scripts using plink

Below is my shell script that I am trying to execute using PLINK on MachineB from MachineA(Windows Machine).
#!/bin/bash
export HIVE_OPTS="$HIVE_OPTS -hiveconf mapred.job.queue.name=hdmi-technology"
hive -S -e 'SELECT count(*) from testingtable1' > attachment22.txt
I am using plink to execute the shell script like below,
C:\PLINK>plink uname#MachineB -m test.sh
Using keyboard-interactive authentication.
Password:
Using keyboard-interactive authentication.
Your Kerberos password will expire in 73 days.
And this is the below error I always get whenever I try to run like above.
sh: HIVE_OPTS= -hiveconf mapred.job.queue.name=hdmi-technology: is not
an identifier
Something wrong with my shell script? or some trailing spaces? I am not able to figure it out. I am running PLINK from windows machine
The sh: prefix on the error message indicates that the script is being executed by sh, not bash.
bash lets you combine setting a variable and exporting it into a single command:
export foo=bar
sh, or at least some older versions of it, require these two actions to be separated:
foo=bar ; export foo
A version of sh that doesn't recognize the export foo=bar syntax will interpret the string foo=bar as a variable name (and an illegal one, since it isn't an identifier).
Either arrange for the script to be executed by bash, or change this:
export HIVE_OPTS="$HIVE_OPTS -hiveconf mapred.job.queue.name=hdmi-technology"
to this:
HIVE_OPTS="$HIVE_OPTS -hiveconf mapred.job.queue.name=hdmi-technology"
export HIVE_OPTS
For that matter, since you're referring to $HIVE_OPTS at the very beginning of your script, it's almost certainly already exported, so you could just drop the export.
(You'll also need to avoid any other bash-specific features.)
So why is the system invoking the shell with sh? The #!/bin/bash syntax is specific to Unix-like systems. Windows generally decides how to execute a script based on the file extension; apparently your system is configured to invoke *.sh files using sh. (You could configure your system, using Folder Options, to invoke *.sh files using bash, but that might introduce other problems.)
I think the -m option to plink is for reading commands to execute on the remote machine from a local file. If my comment about line endings doesn't work, try
plink uname#MachineB test.sh
Make sure test.sh is executable by running
chmod +x test.sh
on MachineB.

Resources