ksh function returns 0 instead of "?" - linux

I encountered a problem, that a ksh command in a legacy ksh script behaves strangely in one enviromment but not another.
These 2 environments have :
the same version of ksh Version AJM 93u+ 2012-08-01
almost the same contents in .profile
same output of cat /proc/version
Linux version 3.10.0-514.10.2.el7.x86_64 (mockbuild#x86-039.build.eng.bos.redhat.com) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC) ) #1 SMP Mon Feb 20 02:37:52 EST 2017
the same output of locale :
LANG=C
LC_CTYPE="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_PAPER="C"
LC_NAME="C"
LC_ADDRESS="C"
LC_TELEPHONE="C"
LC_MEASUREMENT="C"
LC_IDENTIFICATION="C"
LC_ALL=
Inside of this legacy ksh script, there's a function who
executes a sql query
stores the result in a temporary file
removes the title (column name) and \r characte from the temporary file,
assigns the value to a variable,
returns the value of this variable as the function's result by echo
Here's an example of implementation of this function
function get_value {
# A temp file to store sql query result
TEMP_FILE="/tmp/get_value_tmp.txt"
# here's a bloc of code that executes a sql query
# then store the result in ${TEMP_FILE}
# execute_sql_query is just a pseudocode who launches database request program
if execute_sql_query << EOF
# ...
# code do send request against database
# write the result to the tmp file ${TEMP_FILE}
# ...
EOF
then
# removing the title (column name) and \r characte from the temporary file
# assign the value to a variable RET
RET=`tail -n +2 $TEMP_FILE | tr -d '\r'`
# the varible is returned as the result of this function
echo $RET
else
# in case of sql query execution fails
# CR is a variable who gets error code of execute_sql_query
CR=$?
# retrun error code as function result
echo $CR
fi
}
The sql query's result was exported to ${TEMP_FILE}, inside of this ${TEMP_FILE}, we have :
val_str
?
when the variable RET get the value ?
The strange thing is,
in one environment the function returns incorrectly a 0, as it interprets the $RET as $?
in another environment it returns correctly a ?
the function get_value is in a ksh script script_A.ksh
the script_A.ksh is called in another ksh script script_B.ksh
the script script_B.ksh is launched as a background job by nohup ksh script_B.ksh &
Has anyone encountered the same problem, does anyone have some ideas to analyse this issue, please ?
Thanks in advance.

Related

how to return the empty value to the output file

Update: I have updated my idea with coding in details. It's execute in the linux shell.
For I in$(cat list.txt) \\the file contains(1,2,3, ,5,6, ,8,9,10)
do
var1=$(echo $i)
if $var1 -eq null
then
$var1 > output1.txt
else
$var1 = "No Record" \\write a value to the variable
$var1 > output1.txt \\put the value to the same output file above
Fi
done
I am new in linux terminal.
I have 1000 source records (say computer names) to find the dedicate information (say location) using for loop with grep from the database, and save the result to the output file using ">"
However, I found that only 40 records found and cannot match the output with the source records.
`for I in $(cat %filename%)
do
grep location > output1.txt
done`
The script runs successfully, however, I found that some information cannot collect because no return value, so I cannot match those 40 return data to my source records, because I don't know which data belongs to the source record.
Thanks

Check a c file output in Linux

I have 2 files .c which only contain a printf("x")
I am in bash script and i want to check if the values in the printf are for project1.c =20 and for project 2 =10,and then make some changes depending on the values.
How am i supposed to make the comparison in the if command?
This is what i have tried to do,not sure if it is right way.
for d in $1/*/*
do
gcc project1 project1.c
if[ ./project1 = 20 ];then
$project1 =30
else
$project1 =0
fi
gcc project2 project2.c
if[ ./project2 =10 ];then
$project2 = 70
else
$project2 = 0
fi
sum=$project1 + $project2
echo "project1 : $project1 project2: $project2 total grade: $sum" >> grades.txt
done
fi
Your invocation of gcc is wrong. You have to specify the output file:
gcc -o project1 project1.c
Next, in shell, variable substitution is a different process than assignment. So, you can't write $var=foo. The correct syntax is var=foo.
Then, space is a special character (it is used to separate arguments). So var=foo is not the same than var = foo. So, the correct syntax is:
project1=30
Next, in shell, the pattern $(command) is replaced by the result of command. So. I have to do:
if [ $(./project2) == 10 ]; then
Finally, you can do arithmetic using $((calculus)). So, you have to write:
sum=$(($project1 + $project2))

python & shell : how to capture value out side scope in shell script which has embedded python code

The below embedded py code, and get a value from shell , and again in python code scope value updated and to be used shell script scope.. I am not getting the output value of pvar variable, which is at last line
#!/bin/bash
export ans=100
cat << EOF > pyscript.py
#!/usr/bin/python3 -tt
import subprocess
print('............This is Python')
pvar=$ans
pvar=pvar+400
print(" Updated value of pvar =", pvar)
EOF
chmod 770 pyscript.py`enter code here`
$./pyscript.py
echo "The value of pvar in bash = " $pvar
===========
You need to use command substitution to get the results of the script into a bash variable:
pvar=$(./pyscript.py)
echo $pvar
# ............This is Python Updated value of pvar = 500

how to declare variable name with "-" char (dash ) in linux bash script

I wrote simple script as follow
#!/bin/bash
auth_type=""
SM_Read-only="Yes"
SM_write-only="No"
echo -e ${SM_Read-only}
echo -e ${SM_Write-only}
if [ "${SM_Read-only}" == "Yes" ] && [ "${SM_Write-only}" == "Yes" ]
then
auth_type="Read Write"
else
auth_type="Read"
fi
echo -e $auth_type
And when i execute it i got following output with errors.
./script.bash: line 5: SM_Read-only=Yes: command not found
./script.bash: line 6: SM_write-only=No: command not found
only
only
Read
Any one know correct way to declare the variable with "-" (dash)?
EDIT:
have getting response from c code and evaluate the variables for example
RESP=`getValue SM_ Read-only ,Write-only 2>${ERR_DEV}`
RC=$?
eval "$RESP"
from above scripts code my c binary getValue know that script want Read-only and Write-only and return value to script.So during eval $RESP in cause error and in my script i access variable by
echo -e ${SM_Read-only}
echo -e ${SM_Write-only}
which also cause error.
Rename the variable name as follows:
SM_Read_only="Yes"
SM_write_only="No"
Please, don't use - minus sign in variable names in bash, please refer to the answer, on how to set the proper variable name in bash.
However if you generate the code, based on others output, you can simply process their output with sed:
RESP=$(getValue SM_ Read-rule,Write-rule 2>${ERR_DEV}|sed "s/-/_/g")
RC=$?
eval "$RESP"
- is not allowed in shell variable names. Only letters, numbers, and underscore, and the first character must be a letter or underscore.
I think you cant have a dash in your variables names, only letters, digits and "_"
Try:
SM_Read_only
Or
SM_ReadOnly

ksh: assigning function output to an array

Why doesn't this work???
#!/bin/ksh
# array testfunc()
function testfunc {
typeset -A env
env=( one="motherload" )
print -r $env
return 0
}
testfunc # returns: ( one=motherload )
typeset -A testvar # segfaults on linux, memfaults on solaris
testvar=$(testfunc) # segfaults on linux, memfaults on solaris
print ${testvar.one}
note: I updated the above script to print ${testvar.one} from print $testvar to show more precisely what I am trying to accomplish.
I am sure this has been asked before, but I am not sure what to search on and everything I have been trying to use for keywords is not bringing me any answers that relate to my problem.
ksh version:
linux: version sh (AT&T Research) 1993-12-28 s+
solaris: version sh (AT&T Research) 93s+ 2008-01-31
Update:
So another question is, this will run in ksh 93t+ without giving an error, but, it doesn't assign the array properly. I would I go about assigning an array from a function? I tried assigning the array like this also:
typeset -A testvar=$(testfunc)
print ${testvar.one}
But that also didn't work properly.
EDIT
So what is happening here?
typeset -A env=( one="motherload" two="vain" )
print ${env.one}
print ${env.two}
I thought this was how you defined associative arrays, maybe what I was looking at was old but who knows.... seems odd behaviour since this prints out "motherload" and "vain"
Your script works fine for me on Linux with ksh 93t+.
Since it's the same script and you're getting similar errors in two different environments, I would suspect stray characters in the file. Try one of these to show any stray characters that might be present:
hd filename
cat -v filename
hexdump -C filename
If it's simply a matter of DOS line endings, then this will fix that:
dos2unix filename
Edit:
Here's one way to create and populate an associative array in ksh:
$ typeset -A testvar
$ testvar=([one]="motherlode" [two]="vein" [waste]="tailings")
$ echo ${testvar[two]}
vein
$ testvar[ore]="gold"
$ echo ${!testvar[#]} # print the indices of the array
one two waste ore
$ typeset -p testvar # show the current definition of the array
typeset -A testvar=([one]="motherlode" [two]="vein" [waste]="tailings" [ore]="gold")
As you can see, ksh uses bracketed subscripts for arrays. Dotted notation is used for accessing members of a compound variable.
I don't believe ksh functions can return arrays. However, you can use the print technique you have in your function (but add square brackets around the index name) and use eval to do the assignment.
$ typeset -A testvar
$ eval "testvar=($(testfunc))"
or to append to an existing array:
$ eval "testvar+=($(testfunc))"
Unless your function is using associative arrays internally, you don't necessarily need to use them to build your output.
However, if you do, you can parse from the result of typeset -p:
$ result=$(typeset -p env)
$ result=${result#*\(}
$ result=${result%\)*}
$ print result
or iterate through the array:
$ for index in ${!env[#]}; do print -n "[$index]=${env[$index]} "; done; print
You may want to consult the documentation concerning discipline functions and type variables
Here is an alternative to getting any return value from a function using name reference. The value returned will be stored in a variable defined as the first positional argument of the function (not declaring the variable beforehand will work but the variable will be global):
#################################
# Example using compound variable
#################################
function returnCompound {
typeset -n returnVal="$1"
returnVal=( one="motherloadCompound" )
return 0
}
# Declaring the variable to keep it in this scope
# Useful for calling nested functions whitout messing
# with the global scope
typeset myNewCompoundVar
returnCompound myNewCompoundVar
echo "Compound: ${myNewCompoundVar.one}"
##################################
# Example using asssociative array
##################################
function returnMap {
typeset -n myNewMapVar="$1"
myNewMapVar=( [one]="motherloadMap" )
typeset nestedCompoundVar
returnCompound nestedCompoundVar
echo "Compound (Nested) from inside: ${nestedCompoundVar.one}"
return 0
}
# Declaring the variable to keep it in this scope
# Useful for calling nested functions whitout messing
# with the global scope
typeset myNewMapVar
returnMap myNewMapVar
echo "Associative array: ${myNewMapVar[one]}"
echo "Compound (Nested) from outside: ${nestedCompoundVar.one}"
Output:
Compound: motherloadCompound
Compound (Nested) from inside: motherloadCompound
Associative array: motherloadMap
Compound (Nested) from outside:
Important side notes:
Function declarations must be done using the function keyword or else the concept of local scope variable won't be taken under account. In which case the name of your reference variable and global variable might clash if they happen to be the same, resulting in a typeset: invalid self reference error. This can be tested by changing the declaration of the 'returnMap' function.
If you do not declare the return variable before the function call, the variable to which is assigned the return value will be created globally and not limited to the calling scope.

Resources