ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

Need help with QSHELL Scripting

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Need help with QSHELL Scripting

    I am trying to learn QSHELL but I seem to be encountering an error on my first line.

    Below is the code. The script is suppose to check if it received 7 parameters. I am encountering a "token not expected" in the if statement. If the semi-colon is there there error will be "token ; not expected.". If it is not there it will say "then not expected". Whatam I doing wrong?
    Code:
    #!/QOpenSys/usr/bin/sh
    LOG=/home/<user>/log.err.$$.log
    if [ $# != 7 ]; then
      echo "syntax: $0 <user> <hostname> <port> <lib> <file> <source dir> <archive>"
      exit 1
    fi
    export USER=$1
    export HOSTNAME=$2
    export PORT=$3
    export LIB=$4
    export FILE=$5
    export SDIR=$6
    export ADIR=$7
    I am executing the script in QSH.

    If I want to use RPG to create a script dynamically how would I do it?
    Last edited by JustinWithoutAnE; May 25, 2022, 05:33 AM.

  • #2
    Try using -ne instead of ! in your if.

    Comment


    • #3
      That should be -ne instead of !=.

      Comment


      • #4
        When I switch to -ne it still says the semicolon is not expected.

        Comment


        • #5
          I removed the first line and it worked fine with both != and -ne. Looks like you're running a different shell, not Qshell. I forget which shell that is -- probably Bourne or bash.

          BTW, -ne is probably the better option. It does a numeric compare.

          Comment


          • #6
            First, I found the <user> in the LOG= line caused major problems for me. Consider making your LOG line look like this:
            Code:
            LOG=~/log.err.$$.log
            Once I fixed that, your script worked fine for me. If I had to guess, I'd say there's a CCSID problem, the [ and ] characters are prone to major problems with CCSID misconfigurations, which would certainly explain the error you're receiving.

            If that's the problem, you can try an alternate syntax like this:

            Code:
            if test $# != 7; then
              echo "syntax: $0 <user> <hostname> <port> <lib> <file> <source dir> <archive>"
              exit 1
            fi

            Comment


            • #7
              Removing the square brackets did the tricket. Thanks Scott.
              The links to the OpenSSH articles in your site don't seem to be working anymore. Are they available anywhere else?
              Also, what would I need to do if I want to use RPG to dynamically create the sftp script and execute the sftp?

              Comment


              • #8
                Originally posted by JustinWithoutAnE View Post
                The links to the OpenSSH articles in your site don't seem to be working anymore. Are they available anywhere else?
                They are owned and copyrighted by Penton Media who took them offline -- nobody else can legally publish them. You can try taking the links/titles on my site and search the Internet Archive for the old copies, though.

                Originally posted by JustinWithoutAnE View Post
                Also, what would I need to do if I want to use RPG to dynamically create the sftp script and execute the sftp?
                [/QUOTE]

                I wouldn't do that, myself. I'd use Expect where I can use variables, et al, so there'd be no reason to create a script on-the-fly. Honestly, it's very rare that I even need to script sftp at all -- I just use scp, super easy.

                But, I don't see why it wouldn't work? The script is just a normal text file (stream file). Shouldn't be difficult. What are you having trouble with?

                Comment


                • #9
                  Is there a way to put the log generated by scp into a spoolfile?

                  Comment


                  • #10
                    You should be able to use the Rfile utility to write it to a spooled file.

                    I don't remember the details, this is something I haven't done in more than 10 years... For me, if I wanted to print it, it'd be much easier to just load it into Notepad or something and print it.

                    Comment


                    • #11
                      I am giving SCP a try. Below is the body of my code.

                      Code:
                       PGM PARM(&amp;USER &amp;SERVER &amp;PORT &amp;APPCIB &amp;RMTDIR &amp;FILE)
                      /* Input parameters */
                      DCL &amp;USER *CHAR LEN(10)
                      DCL &amp;SERVER *CHAR LEN(20)
                      DCL &amp;PORT *CHAR LEN(5)
                      DCL &amp;APPCIB *CHAR LEN(10)
                      DCL &amp;RMTDIR *CHAR LEN(500)
                      DCL &amp;FILE *CHAR LEN(10)
                      
                      DCL &amp;SCPCMD *CHAR LEN(500)
                      DCL &amp;HOME *CHAR LEN(10) VALUE('/home/')
                      DCL &amp;TODO *CHAR LEN(10) VALUE('/TODO/')
                      DCL &amp;ARCH *CHAR LEN(10) VALUE('/ARCHIVE/')
                      DCL &amp;TODODIR *CHAR LEN(500)
                      DCL &amp;ARCHDIR *CHAR LEN(500)
                      
                      DCL &amp;DATE *CHAR LEN(6)
                      DCL &amp;TIME *CHAR LEN(6)
                      DCL &amp;YMD  *CHAR LEN(6)
                      
                       MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(STDERR1))
                      
                      TIMESTAMP: RTVSYSVAL SYSVAL(QDATE) RTNVAR(&amp;DATE)
                      RTVSYSVAL SYSVAL(QTIME) RTNVAR(&amp;TIME)
                      CVTDAT DATE(&amp;DATE) TOVAR(&amp;YMD) TOFMT(*YMD)  TOSEP(*NONE)
                      
                      CHGVAR VAR(&amp;TODODIR) VALUE(&amp;HOME *TCAT &amp;USER *TCAT '/' *TCAT &amp;APPCIB)
                      CRTDIR DIR(&amp;TODODIR)
                      MONMSG MSGID(CPFA0A0)
                      CHGVAR VAR(&amp;TODODIR) VALUE(&amp;TODODIR *TCAT &amp;TODO)
                      CRTDIR DIR(&amp;TODODIR)
                      MONMSG MSGID(CPFA0A0)
                      CHGVAR VAR(&amp;TODODIR) VALUE(&amp;TODODIR *TCAT &amp;FILE)
                      CPYTOIMPF FROMFILE(&amp;FILE) TOSTMF(&amp;TODODIR) STMFCCSID(1208) RCDDLM(*CRLF) STRDLM(*NONE)
                      
                      CHGVAR VAR(&amp;SCPCMD) VALUE('PATH=$PATH: /QOpenSys/usr/bin &amp;&amp; scp -P=' *TCAT &amp;PORT +
                      *CAT ' ' *CAT &amp;USER *TCAT '@' *TCAT &amp;SERVER *TCAT ' "' *CAT &amp;TODODIR *TCAT '" "' *CAT &amp;RMTDIR *TCAT '"')
                      
                      ADDENVVAR ENVVAR(QIBM_QSH_CMD_OUTPUT) VALUE(NONE)  REPLACE(*YES)
                      ADDENVVAR ENVVAR(QIBM_QSH_CMD_ESCAPE_MSG) VALUE(Y) REPLACE(*YES)
                      
                      QSH CMD(&amp;SCPCMD)
                        MONMSG MSGID(QSH0000) EXEC(DO)
                      ENDDO
                      
                      CHGVAR VAR(&amp;ARCHDIR) VALUE(&amp;HOME *TCAT &amp;USER *TCAT '/' *TCAT &amp;APPCIB *TCAT &amp;ARCH)
                      CRTDIR DIR(&amp;ARCHDIR)
                      MONMSG MSGID(CPFA0A0)
                      CHGVAR VAR(&amp;ARCHDIR) VALUE(&amp;ARCHDIR *TCAT &amp;FILE *TCAT &amp;YMD *TCAT &amp;TIME)
                      MOV OBJ(&amp;TODODIR) TOOBJ(&amp;ARCHDIR)
                      MONMSG MSGID(CPFA0A0)
                      The TODO and ARCHIVE folders already exists but I am only getting the following message for the ARCHIVE folder. It still moves the file from the TODO folder to the ARCHIVE folder.
                      Message ID . . . . . . : CPFA0A0 Severity . . . . . . . : 40
                      Message type . . . . . : Information
                      Date sent . . . . . . : 06/06/22 Time sent . . . . . . : 16:24:58

                      Message . . . . : Object already exists. Object is /home/user/appl/ARCHIVE/.
                      Cause . . . . . : A create operation was attempted on object /home/user/appl/ARCHIVE/. This object already exists.

                      After this I need to add code to clean up the ARCHIVE folder of files older than 30 days.
                      Also, this will be run as a batch job so is there a way to generate a log of the SCP transfer?

                      Comment


                      • #12
                        I've mostly got it with this code earlier but now when I rerun it the other parameters are being added to &RMTDIR and corrupting it. The log says the matching delimiter that should come after &RMTDIR is missing.
                        Can anyone spot why?
                        Code:
                        PGM PARM(&USER &SERVER &PORT &APPCIB &FILE &RMTDIR)
                        /* Input parameters */
                        DCL VAR(&USER) TYPE(*CHAR) LEN(10)
                        DCL VAR(&SERVER) TYPE(*CHAR) LEN(20)
                        DCL VAR(&PORT) TYPE(*CHAR) LEN(5)
                        DCL VAR(&APPCIB) TYPE(*CHAR) LEN(10)
                        DCL VAR(&FILE) TYPE(*CHAR) LEN(10)
                        DCL VAR(&RMTDIR) TYPE(*CHAR) LEN(500)
                        
                        DCL VAR(&SCPCMD) TYPE(*CHAR) LEN(500)
                        DCL VAR(&HOME) TYPE(*CHAR) LEN(10) VALUE('/home/')
                        DCL VAR(&TODO) TYPE(*CHAR) LEN(10) VALUE('/TODO/')
                        DCL VAR(&ARCH) TYPE(*CHAR) LEN(10) +
                        VALUE('/ARCHIVE/')
                        DCL VAR(&TODODIR) TYPE(*CHAR) LEN(500)
                        DCL VAR(&ARCHDIR) TYPE(*CHAR) LEN(500)
                        DCL VAR(&LOG) TYPE(*CHAR) LEN(500)
                        
                        DCL VAR(&DATE) TYPE(*CHAR) LEN(6)
                        DCL VAR(&TIME) TYPE(*CHAR) LEN(6)
                        DCL VAR(&YMD) TYPE(*CHAR) LEN(6)
                        DCL VAR(&QUOTE) TYPE(*CHAR) LEN(1) VALUE('"')
                        
                        /* Error handling variables */
                        DCL VAR(&ERRORSW) TYPE(*LGL)
                        DCL VAR(&MSGID) TYPE(*CHAR) LEN(7)
                        DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(100)
                        DCL VAR(&MSGF) TYPE(*CHAR) LEN(10)
                        DCL VAR(&MSGFLIB) TYPE(*CHAR) LEN(10)
                        DCL VAR(&STATUS) TYPE(*DEC) LEN(10 0)
                        DCL VAR(&SIGNAL) TYPE(*DEC) LEN(10 0)
                        DCL VAR(&RESULT) TYPE(*CHAR) LEN(4)
                        
                        /* Global error monitoring */
                        MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(STDERR1))
                        
                        TIMESTAMP: RTVSYSVAL SYSVAL(QDATE) RTNVAR(&DATE)
                        RTVSYSVAL SYSVAL(QTIME) RTNVAR(&TIME)
                        CVTDAT DATE(&DATE) TOVAR(&YMD) TOFMT(*YMD) +
                        TOSEP(*NONE)
                        
                        /* Check if the Application folder and the TODO folder exists.*/
                        /* Create the folders if they don't exist. */
                        CHGVAR VAR(&TODODIR) VALUE(&HOME *TCAT &USER *TCAT +
                        '/' *TCAT &APPCIB)
                        CRTDIR DIR(&TODODIR)
                        MONMSG MSGID(CPFA0A0)
                        CHGVAR VAR(&TODODIR) VALUE(&TODODIR *TCAT &TODO)
                        CRTDIR DIR(&TODODIR)
                        MONMSG MSGID(CPFA0A0)
                        CHGVAR VAR(&TODODIR) VALUE(&TODODIR *TCAT &FILE)
                        
                        /* Copy file to the TODO folder in the IFS in UTF-8 format */
                        CPYTOIMPF FROMFILE(&FILE) TOSTMF(&TODODIR) +
                        STMFCCSID(1208) RCDDLM(*CRLF) STRDLM(*NONE)
                        /* Build the SCP command to transfer the file */
                        TRANSFER: CHGVAR VAR(&SCPCMD) VALUE('scp -v -P' *BCAT &PORT +
                        *BCAT &QUOTE *TCAT &TODODIR *TCAT &QUOTE +
                        *BCAT &USER *TCAT '@' *TCAT &SERVER *TCAT ':' *TCAT +
                        &QUOTE *TCAT %TRIM(&RMTDIR) *CAT &QUOTE)
                        
                        /* Create the name and path of the transfer log */
                        CHGVAR VAR(&LOG) VALUE('FILE=' *CAT &HOME *TCAT +
                        &USER *TCAT '/' *TCAT &APPCIB *TCAT &TODO +
                        *TCAT 'TRANSFER.LOG')
                        
                        /* Place the transfer log in &LOG. */
                        LOG: ADDENVVAR ENVVAR(QIBM_QSH_CMD_OUTPUT) VALUE(&LOG) +
                        REPLACE(*YES) LEVEL(*JOB)
                        ADDENVVAR ENVVAR(QIBM_QSH_CMD_ESCAPE_MSG) VALUE(Y) +
                        REPLACE(*YES)
                        EXECUTESCP: QSH CMD(&SCPCMD)
                        MONMSG MSGID(QSH0005 QSH0006 QSH0007) EXEC(DO)
                        RCVMSG MSGTYPE(*LAST) MSGDTA(&MSGDTA) MSGID(&MSGID)
                        
                        /* CPF0005 - QSHELL COMMAND ENED "NORMALLY" */
                        IF COND(&MSGID *EQ 'QSH0005') THEN(DO)
                        CHGVAR VAR(&RESULT) VALUE(%SST(&MSGDTA 1 4))
                        CHGVAR VAR(&STATUS) VALUE(%BIN(&RESULT))
                        CHGVAR VAR(&SIGNAL) VALUE(0)
                        ENDDO
                        /* CPF0006 - QSHELL COMMAND ENED WHEN IT RECEIVED A SIGNAL */
                        IF COND(&MSGID *EQ 'QSH0006') THEN(DO)
                        CHGVAR VAR(&RESULT) VALUE(%SST(&MSGDTA 1 4))
                        CHGVAR VAR(&STATUS) VALUE(%BIN(&RESULT))
                        CHGVAR VAR(&SIGNAL) VALUE(-1)
                        ENDDO
                        /* CPF0007 - QSHELL COMMAND ENED DUE TO AN EXCEPTION */
                        IF COND(&MSGID *EQ 'QSH0007') THEN(DO)
                        CHGVAR VAR(&STATUS) VALUE(-1)
                        CHGVAR VAR(&SIGNAL) VALUE(-1)
                        ENDDO
                        IF COND(&STATUS *NE 0) THEN(DO)
                        SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) +
                        MSGDTA('Transfer failed! ' *CAT &FILE +
                        *TCAT &YMD *TCAT &TIME) TOUSR(LIMJF) +
                        MSGTYPE(*ESCAPE)
                        ENDDO
                        ENDDO
                        
                        /* Archive the file */
                        CHGVAR VAR(&ARCHDIR) VALUE(&HOME *TCAT &USER *TCAT +
                        '/' *TCAT &APPCIB *TCAT &ARCH)
                        CRTDIR DIR(&ARCHDIR)
                        MONMSG MSGID(CPFA0A0)
                        CHGVAR VAR(&ARCHDIR) VALUE(&ARCHDIR *TCAT +
                        &FILE *TCAT &YMD *TCAT &TIME)
                        
                        /* Move the file to the ARCHIVE folder */
                        MOV OBJ(&TODODIR) TOOBJ(&ARCHDIR)
                        MONMSG MSGID(CPFA0A0)
                        ENDPGM
                        Last edited by JustinWithoutAnE; June 10, 2022, 06:24 AM.

                        Comment

                        Working...
                        X