Passing arguments to the subshell

I have a shell script which is invoked by passing an argument. The outer shell script calls another subshell and I want the argument passed down to flow down to the subshell.

E.g

Invoking a shell ======>> abc_refresh.ksh NM

Below is the content of abc_refresh.ksh

Value1=$1
Echo $Value
inner_shell.ksh     <<=========  executing another shell inside the shell.

I want the $Value to be passed and recognized by a sql script inside the inner_shell.ksh.

Thanks in advance

edit by bakunin: and thank you - in advance - for enclosing scripts (or script-parts) in code-tags yourself from now on.

export Value1=$1
echo $Value1
inner_shell.ksh

A shell script is - apart from control structures like "if ... then" or "do ... done" - like commands executed on the shells command line. Therefore there is nothing special to take into account when passing arguments to a subshell. Do it like you would do with any other program. For example:

PassArgs.ksh

#! /bin/ksh

print - "Argument passed to PassArgs.ksh: $1"

/path/to/PassArgsSub.ksh "$1"

exit 0

PassArgsSub.ksh

#! /bin/ksh

print - "Argument passed to PassArgsSub.ksh: $1"

exit 0

You could even pass several (or all) arguments to subprocesses by using "$2", "$3", etc. (or "$"). You can try it by replacing "$1" with e.g. "$" in the above example scripts.

I hope this helps.

bakunin

I tried the export option.....The inner_shell.ksh has a sql script and I want to pass the argument value to the sql code. But it is not recognizing it. Any ideas?

can you show both the scripts?

Why don't you post the scripts (or the relevant portions of them) here? It is - if you allow me this analogy - difficult to suggest a move in a chess position you are not allowed to even look at - even for a good player.

Second, why don't you give my suggestion a try? Exporting a variable is like creating a global variable in a normal programming language: bad programming style and very probably leading to problems sooner or later.

bakunin

Below is the content of the abc_refresh.ksh shell

#!/bin/ksh

PLAN=$1 

export PLAN

echo $PLAN

inner_shell.ksh

Below is the content of inner_shell.ksh

#!/bin/ksh

echo "Script On"


bteq > ps_generate_sql.log <<- EOF
.run FILE=/home/i27/tdata_stg_logon.txt
.set errorout STDOUT
.set width 2900

.run file=/home/i276764/ps_refresh/PS_generate_SQL.sql 

.IF errorlevel > 8 then .goto badreturn
.Quit 0

Here is the content of the sql file which uses the argument

                                   select 
			lst.pln
			,lst.databasename
			,lst.table_name
			,lst.view_typ
			from TABLE1 lst
			left join TABLE2 cnt
			on lst.pln=cnt.pln
			and lst.table_name=cnt.table_name
			and lst.view_typ=cnt.view_typ
			where cnt.table_name is null
			and view_typ = 'views_all'
			and pln in ($PLAN))     <<<======Argument used here

I just used the export option for now but can change it to the one given by bakunin

edit by bakunin: grrrr - this is the last time i edit code-tags into your posts - the next time i'll resort to giving infractions for ignoring me.

There are several problems with your code:

1) You use a here-document which isn't closed in the second script:

bteq > ps_generate_sql.log <<- EOF

This says: execute the "bteq"-command, redirect its output (stdout) to "ps_generate_sql.log" and use everything up to "- EOF" as input to it. As there is no second "- EOF" I'm not sure if this will work at all.

2) Another thing is the naming of the here-document: "- EOF" is problematic as whitespace has special meaning in the shell.

3) There is absolutely no reason to use global variables and make one script dependent on the environment another script sets. This is about as error-prone as it can be.

4) The variable you pass cannot be used, because there are different program enviroments at work: a variable expansion can only take place in the shell, but you try to get the SQL-interpreter to expand it - that won't work. You will have to create a temporary copy of the SQL-file with the variable you want to expand, do the replacement by "by hand" (that is: using some UNIX utility) and then throw away this modified copy. I have modified your script accordingly.

5) There are some minor things you should habitually do in your scripts: let them exit with some exit-code and explicitly so, scripts should not just terminate because the end of the input file is reached; always define your variables and do not take them for granted ("typeset"); always use quoting as a means of protection of whitespace and other special characters within your arguments.

Rewrite the scripts the following way:

#!/bin/ksh

typeset PLAN="$1"

print - "PLAN is: \"$PLAN\""
inner_shell.ksh "$PLAN"

exit $?

inner_shell.ksh:

#!/bin/ksh

typeset PLAN="$1"
typeset CmdFile="/home/i276764/ps_refresh/PS_generate_SQL.sql"   # i suppose?
typeset CmdTmp="/tmp/PS_generate_SQL.sql"
typeset -i ErrLvl=0

print - "$0 called with \"$PLAN\""
sed 's/\${PLAN}/'"${PLAN}"'/' $CmdFile > $CmdTmp

bteq > ps_generate_sql.log <<EOF
.run FILE=/home/i27/tdata_stg_logon.txt
.set errorout STDOUT
.set width 2900

.run file="${CmdTmp}" 

.IF errorlevel > 8 then .goto badreturn
.Quit 0
EOF

ErrLvl=$?
rm -rf $CmdTmp

exit $ErrLvl

/home/i276764/ps_refresh/PS_generate_SQL.sql (i believe? if not, change the name and the mechanism of copying/modifying a "blueprint-file" shown above accordingly)

select 
	lst.pln
	,lst.databasename
	,lst.table_name
	,lst.view_typ
from TABLE1 lst
left join TABLE2 cnt
        on lst.pln=cnt.pln
	and lst.table_name=cnt.table_name
	and lst.view_typ=cnt.view_typ
where cnt.table_name is null
	and view_typ = 'views_all'
	and pln in (${PLAN}))

I hope this helps.

bakunin