0

I am trying to run a shell script located on a Linux server from Windows. The shell script does two things:

  • Do a sed command to replace text in an .sql file in the same directory.
  • Run the .sql file with sqlplus.

The shell script:

!/bin/sh
arg1=$1
arg2=$2
arg3=$(echo $arg1 | tr '[:lower:]' '[:upper:]')
arg4=$(echo $arg2 | tr '[:lower:]' '[:upper:]')
echo $arg1
echo $arg2
echo $arg3
echo $arg4   
sed -i "s/$arg3/$arg4/g" sequence.$arg1.sql
sqlplus $arg2/$arg2@MYDB <<EOF
@sequence.$arg1.sql
exit;

(My database is located on the same Linux server.)

1) Script runs correctly when I log in to the server via MobaXterm

  1. Connect to server with userID.
  2. Set my_env.
  3. cd to the shell script's directory.
  4. Run script with ./myscript.sh with arguments.

2) Same shell script runs successfully via .cmd manually

  1. Create a Windows script test.cmd on my Windows PC.
  2. In the .cmd file I have the line:

    plink.exe -ssh userID@Server
    
  3. After the console window pops up, I repeat the steps 2 to 4 and script runs successfully.

What I am failing to do so is to automate the whole process.

Here's the line in my .cmd file which I attempted:

plink.exe -ssh userID@Server /myfilepath/myscript.sh %arg1% %arg2%

I can see the arguments passed correctly using multiple echo in the shell script. However, the shell script fails to locate the .sql file.

Error log:

/mypath/myscript.sh[1]: !/bin/sh^M not found [No such file or directory]
myarg1value
myarg2value
:No such file or directory[myarg1value]
/mypath/myscript.sh[12]: sqlplus: not found [No such file or directory]

I also tried below, but unfortunately with same result:

 plink.exe -ssh userID@Server -m command.txt

Where file command.txt contains:

. my_env
cd /filepath/
./myscript.sh %arg_with_actual_value%

I do not know why it is not working, especially when 2) works and the script is relatively simple.

Do I assume things incorrectly about plink (path, variable, etc.)?

Is Cygwin the only way out?

I tried not to rely on yet another tool as I have been using plink.

EDIT: While the line

sed -i "s/$arg3/$arg4/g" sequence.$arg1.sql

fails to run on the .sh, i can run it on the .cmd file itself via:

plink.exe -ssh userID@Server sed -i "s/%arg3%/%arg4%/g" /myfilepath/sequence.%arg1%.sql

Hence I am suspecting the problem comes from the .sh file not having the required components to run (i.e. set env variable, path, etc)

Alex
  • 1,632
  • 1
  • 12
  • 28
  • 1
    See [Executing command on Plink command line fails with “not found”](https://stackoverflow.com/q/48445395/850848). – Martin Prikryl Jul 24 '19 at 18:22
  • 1
    Interesting is `!/bin/sh^M` in error log. A shell script contains usually at top a shebang like `#! /bin/sh`. A shell script file needs an interpreter and the shebang tells Linux which executable to use as interpreter for executing the script file. This shebang means to use `sh` in directory `/bin` which is usually a symbolic link to really used shell script interpreter executable. `^M` represents a carriage return. A Linux shell script should not contain any carriage return. It should contain only a line feed as line ending of each line. – Mofi Jul 25 '19 at 10:06
  • So make sure `command.txt` on Windows and `myscript.sh` on Linux have only line feeds and no carriage returns, i.e. are UNIX text files and not DOS/Windows text files. Is first line with `. my_env` in `command.txt` correct? – Mofi Jul 25 '19 at 10:06
  • @Mofi As the OP can run the script manually from a shell, it probably means that OP has [some hack](https://stackoverflow.com/q/29603737/850848#29604339) in the environment that allows scripts to be executed even with CRLF. And that hack is not enabled in the Plink environment. So ultimately, it's most likely still the same problem as in the linked question. – Martin Prikryl Jul 25 '19 at 10:20
  • Thank you both for the input. After some reading I found that interactive vs non-interactive session does have different but still couldn't find the cause of my problem. I've done some testing and will add it to the post – Alex Jul 25 '19 at 14:40

1 Answers1

0

This is not a solution but partially fixed some issue, thanks to Martin Prikryl and Mofi's input:

in the command.txt, the following needs to be set:

ORACLE_SID
ORACLE_HOME
PATH

after these are set, the sqlplus and sed will work normally. However, passing values from .cmd through plink to Linux's shell script seems to have issue with the actual value being passed. The variable will have the assigned value along with some unreadable characters. In this case,

sqlplus $arg2/$arg2@MYDB

login fails because arg2 contains some other char.

@sequence.$arg1.sql

this line also fails as it will try to opens 2 files, one being called sequence.myvalue and another one called "%s", which i suspect the assigned variable contains some sort of unreadable nextline character.

EDIT: fixed, we can use the same treatment from sed - run sqlplus directly from plink instead of passing value and running a .sh script in Linux:

sqlplus $arg2/$arg2@MYDB @/myfilepath/sequence.%arg1%.sql
Alex
  • 1,632
  • 1
  • 12
  • 28