In bash -- storing method return value - bash

I'm trying to store a value returned from a method like this: var=$(methodName), but the program never enters the method... It's weird because I do the same thing a few lines earlier (alreadyExists-variable in code sample), and it works fine. I had to do this: var='methodName' to make the program enter the method.
It works, so why care? I'm probably making a mistake, and I need to know what it is and learn from it. Let me know if you need more info to answer the question. Thanks!
overwriteOrNot()
{
echo DEBUG
# This debug string does not print if method is called from "local overwrite=$(overwriteOrNot)"
# but prints if method is called from "local overwrite='overwriteOrNot'"
...
}
local alreadyExists=$(studentNumberExists studentNumber)
if $alreadyExists ; then
# local overwrite=$(overwriteOrNot)
local overwrite='overwriteOrNot'
...

If you're using return, then you need to either directly branch on its result:
if overwriteOrNot; then
: "the function returned 0"
else
: "the function returned something other than 0"
fi
...or store the value of $? immediately after running the function:
overwriteOrNot
local overwrite=$?
Note that return can only return a single-byte integer. If you need to pass content which doesn't fit that type, it needs to be either passed on stdout or in a global variable.

The following:
local overwrite='overwriteOrNot'
assigns a string; it doesn't invoke a function. Instead:
local overwrite=$(overwriteOrNot)
You can check the return value from calling overwriteOrNot with the $? variable, or by checking its numeric return value directly in a conditional statement like:
if overwriteOrNot; then
:
fi
If you assign to overwrite, you can also check its value with any valid test condition such as equality, regular expression match, or emptiness. For example:
if [[ "$overwrite" == "foo" ]]; then
:
fi

Related

Trying to update the value of global variable in Shell Script

myfunc3()
{
echo $1
}
myfunc2()
{
input=$(myfunc3 10)
echo "someting that will be used later"
}
myfunc1() {
var=$(myfunc2) #this does not update the value
# myfunc2 This updates the value
}
input="$(myfunc3 1)"
echo "The new value is: $input"
myfunc1
echo "The new value is: $input"
I have 3 functions that are interrelated. I am trying to update the value of the input variable. I am able to do it when I simply call the function myfunc2 but when I am trying to get the returned value like var=$(myfunc2) as I want to use it for further uses, then the value of the input variable is not updating.
I am very new to shell scripting and I'm not able to understand the reasoning behind it.
Is there any other way to return the value or calling the function?
Thanks in advance

How to make Ruby Mocha mock only check about one parameter

I want to mock this function:
def self.set_segment_info(segment_info, history_record)
history_record.segment_info = segment_info
end
In my test, I want a mock that only confirms that I called set_segment_info with an expected value. I don't care about what I pass in for history_record.
How would I do this? I tried
SegmentHistoryRecord.expects(:set_segment_info).with(:segment_info => expected_segment_info, :history_record => anything)
But that doesn't work.
I ran into this today and ended up doing something like:
SegmentHistoryRecord.expects(:set_segment_info).with(
expected_segment_info,
anything
)
I find it more readable that the do version and it helped me avoid a rubocop issue with too many parameters.
Here's an implementation where, if your function takes a lot of parameters, it's more convenient to specify a value for just the one you care about, instead of for all of them:
expected_segment_info = # ...
SegmentHistoryRecord.expects(:set_segment_info).with() { |actual_parameters| actual_parameters[:segment_info] == expected_segment_info }
(Where, as in the original question, set_segment_info is the function being mocked, and segment_info is the parameter whose value you want to match. Note that the history_record parameter -- and any others that might be present -- don't need to be included.)
SegmentHistoryRecord.expects(:set_segment_info).with() do |param1, param2|
# change below to your verification for :segment_info
# and leave param2 doing nothing, the expectation will ignore param2
param1 == expected_segment_info
end

Execute a Bash script (Shell Script) from postgres function/procedure/trigger

CREATE or replace FUNCTION test() RETURNS boolean AS $$
$filename = '/home/postgres';
if (-e $filename) {
exec /home/postgres/test.sh &
return true; }
return false;
$$ LANGUAGE plperlu;
exec /home/postgres/test.sh & its showing syntax error.
Could you please help how to call bash script into postgres funtion/procedure
Presumably, the code needs to be syntactically valid Perl. So you'll need to clean up a few bits.
CREATE or replace FUNCTION test() RETURNS boolean AS $$
my $filename = '/home/postgres';
if (-e $filename) {
system '/home/postgres/test.sh' and return 1;
}
return;
$$ LANGUAGE plperlu;
I've changed a few things:
I declare the variable $filename using my
I used system instead of exec. exec replaces the current process - effectively never returning to the calling function
system expects to be passed a string. So I've added quotes around the command
and is usually better in flow control statements than && (and always much better than & which is for bit-flipping, not flow control)
Perl doesn't have true and false, so I've replaced true with 1 (which is a true value in Perl). And I've removed the false from the other return statement - the default behaviour of return is to return a false value
I don't have a Postgresql installation to test this on. If it still doesn't work, please tell us what errors you get.
pl/sh exists, and can be used as a procedual language.
https://github.com/petere/plsh

Variable substitution in Shell script

I have declared one variable IS_abc=false, on basis of certain condition I am changing value to IS_abc=true
IS_abc=false
declare -a my_arr
my_arr = ('abc' 'pqr' 'xyz')
....
.... // some operation
IS_abc=true
for i in "${my_arr[#]}"
do
//here i want to access value of $IS_abc as true
//how to do this
done
I have tried accessing using $IS_'$i' , but it raising error as invalid substitution
Tell me if I am doing anything wrong here?
You can use indirect var reference:
my_arr=('abc' 'pqr' 'xyz')
IS_abc=true
var="IS_${my_arr[0]}"
echo "${!var}"
Output:
true
I'm doing it like this:
value=`eval echo \\${IS_${i}}`
There's probably a better way but this should work.

How to use default value when given an empty string in powershell function?

I would like to use the default value when given an empty string. I am hoping for something more elegant then having an if statement to check if $Var is empty, and setting it to a default. Anyone know if this can be achieved? Also need to support powershell version 2.0.
Below is a snippet of what I'm trying to accomplish. Given an empty string I would like it to print "Var: DEFAULT".
$ErrorActionPreference = "Stop"
function Test-Function(
[parameter( Mandatory = $true )][string] $Var = "DEFAULT"
) {
# If Mandatory is set to $true an error is thrown
# "Cannot bind argument to parameter 'password' because it is an empty string."
# When Mandatory is set to $false, $Var is an empty string rather than "DEFAULT"
Write-Host "Var: $Var"
}
$EmptyString = ""
Test-Function -Var $EmptyString
Var is an empty string because you are explicitly passing an empty string. Empty strings are still objects, not null. Your call to Test-Function -Var $EmptyString fails to give you the output you are looking for as you are equating an empty string and null which is false in .Net. Your statement that "When Mandatory is set to $false, $Var is an empty string rather than 'DEFAULT'" is correct as you did pass something, an empty string so the assignment of the value "DEFAULT" was never called.
You could remove the Mandatory=$true in which case your "Default" value is displayed when the parameter is not passed.
function Test-Function(
[parameter( Mandatory = $false )]
[string] $Var = "DEFAULT"
){
Write-Host "Var: $Var"
}
Test-Function
This generates Var: DEFAULT as expected.
Regardless of whether the parameter is mandatory or not, if you pass an empty string the assignment to $Var = "Default" is never reached as $Var has a value of '' which while empty is actually a string.
Test-Function ''
This generates Var: Which may look like wrong but it output the empty string you told it to.
If you want to allow a default value to be assigned when the parameter is not passed use the Mandatory=$false and assign a default value as I did above. If you want to test the value that was passed and assign a default value if it was an empty string you should do that in the begin block of your function.
function Test-Function(
[parameter( Mandatory = $false )]
[string] $Var = "DEFAULT"
){
begin{if([String]::IsNullOrWhiteSpace($Var)){$Var="DEFAULT"}}
process{Write-Host "Var: $Var"}
end{}
}
Test-Function
Test-Function ''
Test-Function 'SomeValue'
This generates the following which I believe to be what you expected:
Var: DEFAULT
Var: DEFAULT
Var: SomeValue
There is no elegant way to do that. At least there is not a built-in way to do so. You can just validate that the string is not null or empty:
function Test {
Param (
[ValidateNotNullOrEmpty()]
[String]
$String = 'DEFAULT'
)
Write-Host -Object "String: $String"
}
Use this inside your function:
If (!($var)) {$var = "DEFAULT"} #basically, if $var doesn't exist, create it
ps. I've just tested it with Mandatory = $false and it works as expected, no idea why it doesn't work for you, what does it do when mandatory = $false?

Resources