How to test script environmental logicals/variables in Unix/bash?

How to test environmental logicals/variables in Unix/bash script with another Unix/bash script?  

I have below script that creates environmental logicals/variables, - those logicals/variables will be used in some other future scripts as well for efficiency reason. The purpose is to use only logicals/variables and not full directories in future scripts.  What would be another script that would test each of theses logicals/variables? Please provide an example if you can.

#!/bin/bash
export DATADIR1=/root/alldirs/2018/data1
export DATADIR2=/root/alldirs/2018/data2
export DATADIR3=/root/alldirs/2018/data3
echo "This script just stopped running"

Open in new window


Any suggestions would be appreciated!
Thank you!
labradorchikAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

SujithData ArchitectCommented:
You need to source the script that sets the environment variables in the second script

Something like the below. where test.sh is the script you have attached in the question -

source test.sh

echo $DATADIR1;
echo $DATADIR2;

Open in new window

Murugesan NagarajanShell_script Automation /bin/bash /bin/bash.exe /bin/ksh /bin/mksh.exe AIX C C++ CYGWIN_NT HP-UX Linux MINGW32 MINGW64 SunOS Windows_NTCommented:
Few more examples:
SETENV.sh
#!/bin/bash
if [[ "bash" == "$0" ]]
then
	echo "Cannot execute SETENV.sh in current shell"
	export SETENVERR=1
else
	export DATADIR1=/root/alldirs/2018/data1
	export DATADIR2=/root/alldirs/2018/data2
	export DATADIR3=/root/alldirs/2018/data3
	export ERROR='echo "This script just stopped running"'
	export SETENVERR=0
fi

Open in new window

UseBaseVersion.sh
#!/bin/bash
if [[ ! -f SETENV.sh ]]
then
	echo "/bin/ls -l SETENV.sh"
	/bin/ls -l SETENV.sh
else
	if [[ -x ./SETENV.sh ]]
	then
		. ./SETENV.sh
		if [[ 0 -eq $SETENVERR ]]
		then
			if [[ ! -d "$DATADIR1" ]]
			then
				echo "DATADIR1 $DATADIR1 No such directory"
				$ERROR
			elif [[ ! -d "$DATADIR2" ]]
			then
				echo "DATADIR2 $DATADIR2 No such directory"
				$ERROR
			elif [[ ! -d "$DATADIR3" ]]
			then
				echo "DATADIR3 $DATADIR3 No such directory"
				$ERROR
			else
				echo "Starting $0"
				echo "$DATADIR1 directory is present PASS"
				echo "$DATADIR2 directory is present PASS"
				echo "$DATADIR3 directory is present PASS"
			fi
		fi
	else
		echo "./SETENV.sh execute permission denied"
		echo /bin/ls -l ./SETENV.sh
		/bin/ls -l ./SETENV.sh
	fi
fi

Open in new window

Current test results:
[output]
$ . ./SETENV.sh
Cannot execute SETENV.sh in current shell
$ source ./SETENV.sh
Cannot execute SETENV.sh in current shell
$ . ./UseBaseVersion.sh
Cannot execute SETENV.sh in current shell
$ source ./UseBaseVersion.sh
Cannot execute SETENV.sh in current shell
$ source $PWD/UseBaseVersion.sh
Cannot execute SETENV.sh in current shell
$ source $PWD/SETENV.sh
Cannot execute SETENV.sh in current shell
[/output]

[output]
$ SETENV.sh
$ echo "DATADIR1: $DATADIR1 : DATADIR2: $DATADIR2 : DATADIR3: $DATADIR3 :"
DATADIR1:  : DATADIR2:  : DATADIR3:  :
$ ./UseBaseVersion.sh
Starting ./UseBaseVersion.sh
/root/alldirs/2018/data1 directory is present PASS
/root/alldirs/2018/data2 directory is present PASS
/root/alldirs/2018/data3 directory is present PASS
[/output]
exit command is not used inside the script, since
source script.sh
used to make current shell/terminal to exit.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
tel2Commented:
You'll see above that Sujith has used the syntax:
    source <scriptname>
while Murugesan has used this more concise alternative, which is basically the same:
    . ./<scriptname>

Some comments on "sourcing" scripts, and the solutions above.
Sujith's solution has ";" at the end of the lines, e.g.
    echo $DATADIR1;
There is no need for the ";" in this case.  It would be needed if he had more than one command on a line.
Murugesan's solution has:
    export DATADIR1=/root/alldirs/2018/data1
as does your script.  From my tests, there is no need to export these variables.  Try it youself to confirm.
There's also no need to start the script which is being "sourced" with a shebang line, so you can remove the "!#/bin/bash".
And the script being sourced doesn't even need to be executable.
HTML5 and CSS3 Fundamentals

Build a website from the ground up by first learning the fundamentals of HTML5 and CSS3, the two popular programming languages used to present content online. HTML deals with fonts, colors, graphics, and hyperlinks, while CSS describes how HTML elements are to be displayed.

labradorchikAuthor Commented:
Thank you everyone for helping and providing your solutions and suggestions! The found the most useful solution from Murugesan, where each directory can be tested to make sure they all exist. Thank you again everyone!!
tel2Commented:
Hi labradorchik,

You can award points as you want to, but are you aware that you can split points so that it's not only the best solution which gets credit?

More comments regarding Murugesan's solution:

      if [[ -x ./SETENV.sh ]]      # The -x includes a check for executability, but SETENV.sh doesn't need to be executable
      then
            . ./SETENV.sh     # Can be more simply written as: ". SETENV.sh", I believe
            if [[ 0 -eq $SETENVERR ]]    # The normal way to write this is: if [[ $SETENVERR -eq 0 ]]

And this code:
                  if [[ ! -d "$DATADIR1" ]]
                  then
                        echo "DATADIR1 $DATADIR1 No such directory"
                        $ERROR
                  elif [[ ! -d "$DATADIR2" ]]
                  then
                        echo "DATADIR2 $DATADIR2 No such directory"
                        $ERROR
                  elif [[ ! -d "$DATADIR3" ]]
                  then
                        echo "DATADIR3 $DATADIR3 No such directory"
                        $ERROR
                  else
will report only the first non-existent directory, but that's probably OK for most applications.

And the "quotes" can be removed from this kind of bash statement:
      if [[ ! -d "$DATADIR1" ]]
Murugesan NagarajanShell_script Automation /bin/bash /bin/bash.exe /bin/ksh /bin/mksh.exe AIX C C++ CYGWIN_NT HP-UX Linux MINGW32 MINGW64 SunOS Windows_NTCommented:
#!/bin/bash
# >> TEL2
# >> You can award points as you want to
# Agreed :)
# Sample code1...
if [[ ! -f SETENV.sh ]]
then
      echo "\$PWD $PWD"
      echo "/bin/ls -l SETENV.sh"
      /bin/ls -l SETENV.sh
else
      # The -x includes a check for executability, but SETENV.sh doesn't need to be executable
      # Agreed :)
      # @labradorchik can change ./ to required directory(Example:$PWD) or remove ./ based on requirement
      SETENVPATH=$(/bin/dirname SETENV.sh)
      if [[ "." = "$SETENVPATH" ]]
      then
            SETENVPATH="$PWD"
      fi
      echo $SETENVPATH
      if [[ -f "$SETENVPATH/SETENV.sh" ]]
      then
            . "$SETENVPATH/SETENV.sh"
            # I was from C++ C(Linux/UNIX/AIX/SunOS/HP-UX/CYGWIN_NT)
            # To remove future exceptions (due to new joinees) C C++ and Makefile(using shell script at all OS)
            # used to prefer this format in C++, C Makefile and shell scripting.
            # Hence followed this way
            if [[ 0 -eq $SETENVERR ]]
            then
                  if [[ ! -d "$DATADIR1" ]]
                  then
                        echo "DATADIR1 $DATADIR1 No such directory"
                        $ERROR
                  elif [[ ! -d "$DATADIR2" ]]
                  then
                        echo "DATADIR2 $DATADIR2 No such directory"
                        $ERROR
                  elif [[ ! -d "$DATADIR3" ]]
                  then
                        echo "DATADIR3 $DATADIR3 No such directory"
                        $ERROR
                  else
                        echo "Sample test1 $0"
                        echo "$DATADIR1 directory is present PASS"
                        echo "$DATADIR2 directory is present PASS"
                        echo "$DATADIR3 directory is present PASS"
                  fi
            fi
      else
            echo "\$PWD $PWD"
            echo /bin/ls -l "$SETENVPATH/SETENV.sh"
            /bin/ls -l "$SETENVPATH/SETENV.sh"
      fi
fi
# >> will report only the first non-existent directory.
# Updated Sample code2
# Thank you TEL2 for all comments.
if [[ ! -f SETENV.sh ]]
then
      echo "\$PWD $PWD"
      echo "/bin/ls -l SETENV.sh"
      /bin/ls -l SETENV.sh
else
      if [[ -f "$SETENVPATH/SETENV.sh" ]]
      then
            . "$SETENVPATH/SETENV.sh"
            #OR
            #source "$SETENVPATH/SETENV.sh"
            if [[ 0 -eq $SETENVERR ]]
            then
                  if [[ -d "$DATADIR1" && -d "$DATADIR2" && -d "$DATADIR3" ]]
                  then
                        echo "Sample test2 $0"
                        echo "$DATADIR1 directory is present PASS"
                        echo "$DATADIR2 directory is present PASS"
                        echo "$DATADIR3 directory is present PASS"
                  else
                        if [[ ! -d "$DATADIR1" ]]
                        then
                              echo "DATADIR1 $DATADIR1 No such directory"
                              $ERROR
                        fi
                        if [[ ! -d "$DATADIR2" ]]
                        then
                              echo "DATADIR2 $DATADIR2 No such directory"
                              $ERROR
                        fi
                        if [[ ! -d "$DATADIR3" ]]
                        then
                              echo "DATADIR3 $DATADIR3 No such directory"
                              $ERROR
                        fi
                  fi
            fi
      else
            echo "\$PWD $PWD"
            echo /bin/ls -l "$SETENVPATH/SETENV.sh"
            /bin/ls -l "$SETENVPATH/SETENV.sh"
      fi
fi

$ ./29099107.sh
$PWD /home/murugesandins
/bin/ls -l SETENV.sh
/bin/ls: cannot access 'SETENV.sh': No such file or directory
$PWD /home/murugesandins
/bin/ls -l SETENV.sh
/bin/ls: cannot access 'SETENV.sh': No such file or directory

Open in new window

$ ./29099107.sh
/home/murugesandins
Sample test1 ./29099107.sh
/root/alldirs/2018/data1 directory is present PASS
/root/alldirs/2018/data2 directory is present PASS
/root/alldirs/2018/data3 directory is present PASS
Sample test2 ./29099107.sh
/root/alldirs/2018/data1 directory is present PASS
/root/alldirs/2018/data2 directory is present PASS
/root/alldirs/2018/data3 directory is present PASS

Open in new window

tel2Commented:
Thanks for the improvements, Murugesan.

           # I was from C++ C(Linux/UNIX/AIX/SunOS/HP-UX/CYGWIN_NT)
            # To remove future exceptions (due to new joinees) C C++ and Makefile(using shell script at all OS)
            # used to prefer this format in C++, C Makefile and shell scripting.
            # Hence followed this way
            if [[ 0 -eq $SETENVERR ]]

Q1. Can you prove that issue with C++/C?
Q2. Why are you applying this strange requirement of some old C++/C version to bash?

Q3. Why do you use "quotes" in tests like this?:
   if [[ ! -d "$DATADIR1" ]]
Murugesan NagarajanShell_script Automation /bin/bash /bin/bash.exe /bin/ksh /bin/mksh.exe AIX C C++ CYGWIN_NT HP-UX Linux MINGW32 MINGW64 SunOS Windows_NTCommented:
>> Can you prove that issue with C++/C?
#include <stdio.h>
int main()
{
        int incidentId = 0;
        if ( incidentId = 29099107 )
        {
                printf( "Sample exception %d\n", incidentId);
        }
        else
        {
                printf( "Handled exception %d\n", incidentId);
        }
        return 0;
}
// $ ./a.out
// Sample exception 29099107

Open in new window

I agree based on warnings (-Wall), we can remove such exception. However when the source code count increases(thousands of source files... from open source), that becomes difficult.
$ /bin/sed "s/\(incidentId \)\(=\)\( 29099107\)/\3\2\1/;"  29099107.c
$ /usr/bin/gcc -g -Wall 29099107.c -o ./a.out
29099107.c: In function ‘main’:
29099107.c:5:16: error: lvalue required as left operand of assignment
  if ( 29099107 = incidentId )

Open in new window

>> Assume that a developer writing the script using variable operator value, same used to be followed using C C++. Hence followed the same.

>> Why do you use "quotes" in tests like this?:
I cannot remember the error faced during 2005 to 2006 => few errors happened using common Makefile at all platforms.

echo "Thank you and welcome :) "| /usr/bin/wc
tel2Commented:
Hi Murugesan,

Q4. Regarding the C/C++ code you've provided, I don't know much C, but why are you using the "=" (assignment operator) instead of the "==" (equivalence operator), in this line?:
       if ( incidentId = 29099107 )
I expect that would always return a true result because the assignment succeeds.

Q5. Does this solve the problem?:
       if ( incidentId == 29099107 )

>> Why do you use "quotes" in tests like this?:
> I cannot remember the error faced during 2005 to 2006 => few errors happened using common Makefile at all platforms.

I'm not talking about Makefiles.  I'm taking about the "quotes" in bash tests like this:
          if [[ ! -d "$DATADIR1" ]]
Please answer question Q3 again, plus Q4 & Q5.

Thanks.
Murugesan NagarajanShell_script Automation /bin/bash /bin/bash.exe /bin/ksh /bin/mksh.exe AIX C C++ CYGWIN_NT HP-UX Linux MINGW32 MINGW64 SunOS Windows_NTCommented:
Q3)
I cannot remember the code (script @ all OS) error happened because of parsing EDI files => it was present in given script using more conditional operators => or, and xor /bin/sed
Release code (all binaries including setup.sh) need to meet all requirements mentioned in design documents.
>> It was something like standardized version of UNIX version 5 => present in Design of UNIX operating system from Maurice J Bach
Q4)
>> I expect that would always return a true result because the assignment succeeds.
During 2005/2006 given source code was having that issue due to SIGSEGV
Using -g recompilation, reproducing the error, ulimit -c unlimited and gdb found that error.
Hence proceeded using "value operator variable"
After resolving that, we have removed -g, ulimit and re compiled.
Q5)
>> if ( incidentId == 29099107 )
developer may miss = operator here
tel2Commented:
Hi Murugesan,

Q5)
>> if ( incidentId == 29099107 )
> "developer may miss = operator here"

That does not answer my question.  Please read my question Q5 from post #42563248, and then answer it.

Thanks.
Murugesan NagarajanShell_script Automation /bin/bash /bin/bash.exe /bin/ksh /bin/mksh.exe AIX C C++ CYGWIN_NT HP-UX Linux MINGW32 MINGW64 SunOS Windows_NTCommented:
Q5. Does this solve the problem?:
       if ( incidentId == 29099107 )
>> Why do you use "quotes" in tests like this?:

when DATADIR1 may have spaces (writing the code to execute the script at all OS)
Sample:
C:\PROGRA~2\INTERN~1 => /cygdrive/c/PROGRA~2/INTERN~1 OR /cygdrive/c/Program Files (x86)/Internet Explorer
Faced that issue when directory was having special characters => multi language support at all OS
written generalized script across platforms.
tel2Commented:
This question of mine:
                 Q5. Does this solve the problem?:
                      if ( incidentId == 29099107 )

has nothing to do with this other question of mine:
                 >> Why do you use "quotes" in tests like this?:
The "quotes" question was Q3.

So please answer this question in regard to the C code sample you provided at the top of post #42563241:
                 Q5. Does this solve the problem?:
                      if ( incidentId == 29099107 )
Murugesan NagarajanShell_script Automation /bin/bash /bin/bash.exe /bin/ksh /bin/mksh.exe AIX C C++ CYGWIN_NT HP-UX Linux MINGW32 MINGW64 SunOS Windows_NTCommented:
if ( incidentId == 29099107 ) => Yes, it solves the problem.

C C++ programmer used to write "if ( incidentId = 29099107 )" instead of "if ( incidentId == 29099107 )"
missing = operator.
This used to cause issues over most of the data types.
Hence informed the team to have value on right and variable on left.
Informed the developers to proceed the same way even when using script => Since using that most of the times (script or Makefile or source code) => makes (C CPP) developer not to write "variable = value" format.
Hence proposed value = variable inside script too.
I agree variable = value work using script. However making them to write => will prevent future (C CPP ) developer's exceptions.
tel2Commented:
There is no need to bring those strange C/C++ habits into bash, especially in a forum where:
a) You haven't documented/explained the reason for the odd syntax in every solution that you provide it.
b) Many of the readers will  quite likely never program in C/C++.
Murugesan NagarajanShell_script Automation /bin/bash /bin/bash.exe /bin/ksh /bin/mksh.exe AIX C C++ CYGWIN_NT HP-UX Linux MINGW32 MINGW64 SunOS Windows_NTCommented:
ok, got it. Here after I won't merge script to C/C++ programming oriented.
Sure, I will follow the same.
>> Many of the readers
I understood.
Thank you tel2.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Bash

From novice to tech pro — start learning today.