Copy file from remote server through lftp - linux

I'm new to linux scripting. I want to copy file from remote server to current server(executing or client server),required cert & key files are already installed on my server(client server). below commands work when I execute it individually in sequence but, after Integrating into a .sh script it doesnt!
--My Script--
lftp -u username,xxx -p 2121 remoteServer.net;
set ssl:cert-file /abc/def/etc/User_T.p12;
set ssl:key-file abc/def/etc/User_T.p12.pwd;
lftp -e 'set net:timeout 10; get /app/home/atm/feed.txt -o /com/data/';

man lftp:
-f script_file
Execute commands in the file and exit. This option must be used
alone without other arguments (except --norc).
-c commands
Execute the given commands and exit. Commands can be separated
with a semicolon, `&&' or `||'. Remember to quote the commands
argument properly in the shell. This option must be used alone
without other arguments (except --norc).

Use "here document" feature of the shell:
lftp <<EOF
set...
open...
get...
EOF

Thanks lav for your suggestion, I found that my script was not executing second line so added continuation like
<< SCRIPT
& ended script with SCRIPT
removed all semi colon... Its working

Related

How to run shell script located on Linux server from Windows environment?

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
Connect to server with userID.
Set my_env.
cd to the shell script's directory.
Run script with ./myscript.sh with arguments.
2) Same shell script runs successfully via .cmd manually
Create a Windows script test.cmd on my Windows PC.
In the .cmd file I have the line:
plink.exe -ssh userID#Server
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)
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

Use bash to send command to LFTP and then staying in interactive mode

Forgive the phrasing; haven't done anything with bash for 15 years.
I am trying to write a shell script that will run and connect to lftp and then execute several commands, specifically:
set ftp:ssl-force on
set ftp:ssl-protect-data on
set ssl:verify-certificate no
I then want to remain inside lftp so that I can send additional commands (e.g., I don't know what filename I am downloading until I can do an ls on a remote directory).
When I try to write a bash script to pipe commands to lftp, it works but then also immediately quits lftp when it reaches the last line of the script. Is there a way to prevent that from happening?
Use lftp's -e option:
lftp -e 'set ftp:ssl-force on; set ftp:ssl-protect-data on; set ssl:verify-certificate no'
According to lftp's manual:
-e commands
Execute given commands and don't exit.
concat stdin after your script
cat yourscript /dev/stdin | your_tftp_command
cat also accept - as special filename argument for stdin
cat yourscript - | your_tftp_command

Getting "Unknown command" when using "lftp -e"

I'm working on a bash script to automate FTP sessions, so I can run the same commands on multiple servers automatically)
lftp -u username,password ip_address -e **FILE_WITH_COMMANDS**
So the problem is that I somehow can't use a file with -f because I get an error like this:
Unknown command `commands'.
Does anybody know how to get around this problem?
Thank you very much!
To execute commands loaded from a file, use the -f switch:
-f execute commands from the file and exit
The -e switch is for executing a command specified on the command-line:
-e execute the command
So when you use -e commands, the lftp interprets it as a request to run the commands command. And there's no commands command, hence the error.
See also https://lftp.yar.ru/lftp-man.html

Execute a list of Unix commands using ssh

I want to run the same set of Unix commands on multiple machines. I am aware of ssh and something like the below. I want to write a shell script to do this. I have access to bash and ksh and I'm on Linux Red Hat 5.
ssh root#ip "echo \$HOME"
However, I have 2 questions:
I keep getting prompted for a password. How can I have it not prompt me and enter the password automatically?
How can I execute multiple commands?
You should use key based authentification, possibly coupled with ssh-agent to remember key passphrase.
You can invoke sh -c as the command, and pass it a string containing the list of command to execute. ssh invoke a shell on the remote machine, so you can pass a list of command as a string.
For example:
$ ssh user#ip "echo 'Hello world'; whoami; cd / ; ls"
Use ssh-agent to set up authentication for all commands. Or put your multiple commands into a single shell script.
Send a list of commands to the remote shell. Possible solutions:
use ", escape line breaks to format code and end each substatement with ;.
Disadvantage: " should not be used inside the command list.
ssh user#ip "\
echo 'Hallo sir, how are you doing?';\
whoami;\
cd /;\
ls\
"
use ' and format code with regular line breaks.
Disadvantage: ' should not be used inside the command list.
ssh user#ip '
echo "Hallo sir, how are you doing?"
whoami
cd /
ls
'
Note: using " or ' inside the respective statements will not necessarily result in an error. Though you may get unsuspected results.

Avoid gnome-terminal close after script execution?

I created a bash script that opens several gnome-terminals, connect to classroom computers via ssh and run a script.
How can I avoid that the gnome-terminal closes after the script is finished? Note that I also want to be able to enter further commands in the terminal.
Here is an example of my code:
gnome-terminal -e "ssh root#<ip> cd /tmp && ls"
As I understand you want gnome-terminal to open, have it execute some commands, and then drop to the prompt so you can enter some more commands. Gnome-terminal is not designed for this use case, but there are workarounds:
Let gnome-terminal run bash and tell bash to run your commands and then start a new bash
$ gnome-terminal -- bash -c "echo foo; echo bar; exec bash"
or if the commands are in a script
$ gnome-terminal -- bash -c "./scripttorun; exec bash"
The first bash will terminate once all the commands are done. But the last command is a new bash which will then just keep running. And since something is still running gnome-terminal will not close.
Let gnome-terminal run bash with a prepared rcfile which runs your commands
Prepare somercfile:
source ~/.bashrc
echo foo
echo bar
Then run:
$ gnome-terminal -- bash --rcfile somercfile
bash will stay open after running somercfile.
i must admit i do not understand completely why --rcfile has this behaviour but it does.
Let gnome-terminal run a script which runs your commands and then drops to bash
Prepare scripttobash:
#!/bin/sh
echo foo
echo bar
exec bash
Set this file as executable.
Then run:
$ gnome-terminal -- ./scripttobash
for completeness
if you just want to be able read the output of the command and need no interactivity
go to preferences (hamburger button -> preferences)
go to profiles (standard or create a new one)
go to command tab
when command exits -> hold the terminal open
i recommend to create a new profile for just for this use case.
use the profile like this:
gnome-terminal --profile=holdopen -- ./scripttorun
Every method has it's quirks. You must choose, but choose wisely.
I like the first solution. it does not need extra files or profiles. and the command says what it does: run commands then run bash again.
All that said, since you used ssh in your example, you might want to take a look at pssh (parallel ssh). here an article: https://www.cyberciti.biz/cloud-computing/how-to-use-pssh-parallel-ssh-program-on-linux-unix/
Finally this one works for me:
gnome-terminal --working-directory=WORK_DIR -x bash -c "COMMAND; bash"
Stack Overflow answer: the terminal closes when the command run inside it has finished, so you need to write a command that doesn't terminate immediately. For example, to leave the terminal window open until you press Enter in it:
gnome-terminal -e "ssh host 'cd /tmp && ls'; read line"
Super User answer: Create a profile in which the preference “Title and Command/When command exits” is set to “Hold the terminal open”. Invoke gnome-terminal with the --window-with-profile or --tab-with-profile option to specify the terminal name.
Run with -ic instead -i to make terminal close bash proccess when you close your terminal gui:
gnome-terminal -e "bash -ic \"echo foo; echo bar; exec bash\""
As of January 2020, the -e option in gnome-terminal still runs properly but throws out the following warning:
For -e:
# Option “-e” is deprecated and might be removed in a later version
of gnome-terminal.
# Use “-- ” to terminate the options and put the command line to
execute after it.
Based on that information above, I confirmed that you can run the following two commands without receiving any warning messages:
$ gnome-terminal -- "./scripttobash"
$ gnome-terminal -- "./genericscripttobash \"echo foo\" \"echo bar\""
I hope this helps anyone else presently having this issue :)
The ideal solution would be to ask for a user input with echo "Press any key".
But if double-click in Nautis or Nemo and select run in a terminal, it doesn't seem to work.
In case of Ubuntu a shell designed for fast start-up and execution with only standard features is used, named dash I believe.
Because of this the shebang is the very first line to start with to enable proper use of bash features.
Normally this would be: #!/bin/bash or similar.
In Ubuntu I learned this should be: #!/usr/bin/env bash.
Many workarounds exist to keep hold of the screen before the interpreter sees a syntax error in a bash command.
The solution in Ubuntu that worked for me:
#!/usr/bin/env bash
your code
echo Press a key...
read -n1
For a solution applicable to any terminal, there is a script that opens a terminal, runs the command specified and gives you back the prompt in that new terminal:
https://stackoverflow.com/a/60732147/1272994
I really like the bash --rcfile method
I just source ~/.bashrc then add the commands I want to the new startrc.sh
now my automated start.sh work environment is complete... for now 😼
If running a bash script just add gedit afile to the end of the script and that will hold gnome-terminal open. "afile" could be a build log which it was in my case.
Did not try just using gedit alone but, that would properly work too.
Use nohup command.
nohup gnome-terminal -e "ssh root# cd /tmp && ls"
Hope this will help you.

Resources