Pages

Saturday, November 2, 2013

SSH Login with Password in Shell Script

Few weeks before I have written a shell script which invoke a API to fetch the data from the corporate server. Initially, I used to run this script manually based on the demand. After couple of weeks I have scheduled the same script using cron in one of our central servers to trigger it 2 days a week.

The first time script was triggered on time and the report was generated without any issues. But for the second schedule, the report didn't arrive on time. I was about to present few statistics from that report to all of my peers in a meeting. The average execution time of that script time is around 5 seconds, but it didn't arrive for 2 minutes and we all are waiting. I didn't have to time check the issue and immediately, I logged in to the server and executed it manually and  presented the same without any issues.

I was very curious about the issue and waiting for the meeting to be over. Post meeting, I have modified the cron schedule to trigger it for the next minute. Surprisingly it executed perfectly fine. I got even more curious and no clue about the issue. I thought the server might down at that time or this process might have been killed by the administrator.

Strangely, 2 days later the issue was repeated again on the next schedule. This time I got frustrated and setup the cron logs to track the issue. During the third failure, I was able to troubleshoot the root cause with the generated logs. It was not a problem with the sever or process or the schedule. It was the problem with the API. This API can be accessed using only with my official login credentials hence it was prompted for the password and failed for all the three times.

But, Why it was not prompting before? I have executed the same script for more than 100 times manually. None of the occasions it prompted for the password. That was the time I blamed myself for not reading the API docs properly. It says if the user logged in to the server in past 72 hours it will not prompt for the password. Bingo!

Now, I need to automate the manual process of entering the password. I don't want to waste much time on it. So immediately I went to one of my QA's desk. He used to write similar kind of automated tests to test our product for full time. He suggested me to use Perl and Expect function. I was happy and taken few examples from him. I have started to installed Perl on my system and that example works just like that.

I was excited and uploaded the same script to the central server via SFTP and executed it. The output was shocking.


[siva@server ~]$ perl
perl: Command not found.

At this point I have realized that I need to request and follow up few people who manages this server. They are located in different geographical region. So the communication/justification/approval time would be much longer. So Perl was not a good idea at this time and started to look for alternatives. Few  people already had this question on some Q &A sites and the best answers recommended to use the same expect function in shell script.

Since I have already set up the certification based authentication, I have started with the very simple snippet which is almost same as my previously written Perl script.


#!/usr/bin/expect -f
spawn ssh siva@server
expect "\[siva@server ~\]$"
send "./scripts/report_abc.sh\r"
expect "Password:"
send "mypassword\r"
expect "\[siva@server ~\]$"
send "quit"

It was just working without any issues. So I have uploaded the script to the server executed it. It failed with

 
/usr/bin/expect -f : bad interpreter: No such file or directory

Another shock. But luckily someone had the same question in Ubuntu forums  and the accepted answer suggested to run it by invoking the commands from a file.


/usr/bin/env expect -f /home/siva/file.txt


Wow. It worked. Now I am presenting the ~live statistics to my team without any issues for past 2 months.

Content of file.txt


spawn ssh siva@server
expect "\[siva@server ~\]$"
send "./scripts/report_abc.sh\r"
expect "Password:"
send "mypassword\r"
expect "\[siva@server ~\]$"
send "quit"




No comments:

Post a Comment