1

I am running a shell script within the Jenkins pipeline and i want to print into a text file latest files names column created by date, i dont want want to print time & date column etc, just anything after 9 which are files names and print to into a txt file..

codes are as below:

Note: when i run those commands in bash all work fine, \ is added as Jenkins does not seems to like the $ without the dollar sign all run fine in shell.

out put in shell is like this:

 bash.sh
        home
        testfile.txt
        blabla.csv
        rtyuioiuytrty.xml

like above I would like to be printed in Jenkinsfile. Jenkins does not seem to like to run those codes as below: I also tried this loop

node ('node') {
    stage ('SSH To server') {
      sshagent(credentials: ['sshkey']) {
        script {
        sh"""ssh -o StrictHostKeyChecking=no user@servername << EOF

      if [ \$? -ne 0 ]; then
                    echo " Error while connecting SSH "
                    exit 1
            fi  

     cd ${SOURCE_PATH}
     if [ \$? -ne 0 ]; then
           echo "Error while doing change directory \${SOURCE_PATH} "
           exit 1
     fi

     ls -lrt | grep "$(date '+%b %e')" |awk '{ s =""; for (i = 9; i <= NF; i++) s = s $i " "; print }'


        exit
        EOF
   """
Ram
  • 1,154
  • 6
  • 22
stevek
  • 11
  • 1
  • 4
  • This seems related to https://stackoverflow.com/questions/52484213/using-nested-command-substitution-in-jenkins-pipeline-sh-step but it would be good to see how exactly you are putting this in on the Jenkins side. Is this in a Groovy script or in a dialog box in the Jenkins web UI somewhere? – tripleee Jul 17 '19 at 05:02
  • I am doing like this : sh '''' ssh name@server << EOF bash script here, and then '''EOF – stevek Jul 17 '19 at 07:42
  • 1
    Please [edit] the question to show this with proper code formatting and more context. – tripleee Jul 17 '19 at 08:01
  • 1
    Instead of """ (3 double quotes) you can use ''' (3 single quotes). https://stackoverflow.com/questions/6761498/whats-the-difference-of-strings-within-single-or-double-quotes-in-groovy – hakamairi Jul 17 '19 at 12:35
  • Multiline shell scripts should not really be inlined into Jenkins Pipeline for this and other reasons. Consider converting this to Groovy, or at worst just putting it in a script and executing the script. – Matthew Schuchard Jul 17 '19 at 13:02

1 Answers1

3

Welcome to the hell of escaping in Jenkins :-)

probably the below command will help you

node(''){
  sh "touch test.txt"
  sh """ls -lrt | grep \"\$(date '+%b %e')\" |awk '{ s =\"\"; for (i = 9; i <= NF; i++) s = s \$i \" \"; print s }'"""
}

The gist is, you will have to escape double quotes and the dollar.

Answer for your updated code snippet is

 sh"""ssh -o StrictHostKeyChecking=no user@servername << EOF
        if [ \$? -ne 0 ]; then
            echo \" Error while connecting SSH \"
            exit 1
        fi  
        cd \${SOURCE_PATH}
        if [ \$? -ne 0 ]; then
            echo \"Error while doing change directory \${SOURCE_PATH} \"
            exit 1
        fi
        ls -lrt | grep \"\$(date '+%b %e')\" | awk '{ print \\\$9}'
        exit
        EOF
    """
Ram
  • 1,154
  • 6
  • 22
  • org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: WorkflowScript: 36: illegal string body character after dollar sign; solution: either escape a literal dollar sign "\$5" or bracket the value expression "${5}" @ line 36, column 20. sh """ls -lrt | grep "$(date '+%b %e')" |awk '{ s =""; for (i = 9; i <= NF; i++) s = s $i " "; print }'"" – stevek Jul 17 '19 at 09:08
  • The above code snippet that I posted echos `test.txt` in my case. Did you execute the exact code snippet and got the error? Could you provide your updated command ? – Ram Jul 17 '19 at 11:25
  • ```Running in Durability level: MAX_SURVIVABILITY [Pipeline] Start of Pipeline [Pipeline] node Running on agent01 in /var/jenkins_home/workspace/sandbox-pipeline [Pipeline] { [Pipeline] sh + touch test.txt [Pipeline] sh + ls -lrt + date +%b %e + grep Jul 17 + awk { s =""; for (i = 9; i <= NF; i++) s = s $i " "; print s } test.txt [Pipeline] } [Pipeline] // node [Pipeline] End of Pipeline Finished: SUCCESS``` – Ram Jul 17 '19 at 11:27
  • node ('Node') { stage ('SSH To server') { sshagent(credentials: ['sshkey]) { script { sh"""ssh -o StrictHostKeyChecking=no user@server << EOF – stevek Jul 17 '19 at 12:04
  • if [ \$? -ne 0 ]; then echo " Error while connecting SSH " exit 1 fi cd ${SOURCE_PATH} if [ \$? -ne 0 ]; then echo "Error while doing change directory \${SOURCE_PATH} " exit 1 fi ls -lrt | grep "$(date '+%b %e')" |awk '{ s =""; for (i = 9; i <= NF; i++) s = s $i " "; print }' exit EOF"" – stevek Jul 17 '19 at 12:04
  • sorry i cant add it properly here,, i need to add those codes above maybe so you can seeit how i am running – stevek Jul 17 '19 at 12:05
  • Could you please update your question with this script? It’s hard to read here – Ram Jul 17 '19 at 12:06
  • Thanks Ram, iupdated the question not to sure you can see it – stevek Jul 17 '19 at 12:12
  • Thanks again Sham, still the awk did not print just the files names i am after, printed date and time.. sounds like did not work awk – stevek Jul 17 '19 at 14:50
  • 1
    U were right. The awk was not printing the 9th field. It wasn't escaped properly. I have updated the answer, basically, you have to use three escape characters. `\\\$9` – Ram Jul 19 '19 at 08:59
  • You deserve more upvotes for the accurate "hell of escaping in Jenkins" comment alone. :) – StoneThrow Jul 30 '21 at 18:25