unexpected behavior of shell script - linux

I'm quite confused When I try to ouput some patterns with * in shell.The code is:
#!/bin/bash
for i in {1..10}
do
tmpstr=""
for ((c=1;c<=i;c++))
do
tmpstr=$tmpstr'*'
done
echo $tmpstr #add some string after tmpstr will work
done
The output shows me the result of ls command in each line which is unexpected. And the code will works fine if I add any string after echo $tmpstr.For example,echo $tmpstr" " .So how to understand this?

Your script is generating the following for tmpStr
*
**
***
etc.
which results in the following echo statements
echo *
echo **
echo ***
etc.
The shell interprets the * as a wildcard and expands it by listing all the files in the current directory.
Note that if you put quotes around the shell variable:
echo "$tmpstr"
The shell does not expand the wildcard characters and the output is
*
**
***
****
*****
******
*******
********
*********
**********

Related

Bash script with multiline heredoc doesn't output anything

I'm writing a script to send SQL output in mail, but it is not executing successfully and is not generating the output I want.
The query generates two columns with multiple rows. How can I generate the output in table format as below?
Below is my code:
#!/bin/bash
ORACLE_HOME= **PATH
export ORACLE_HOME
PATH=$PATH:$ORACLE_HOME/bin
export PATH
TNS_ADMIN= ** PATH
export TNS_ADMIN
today=$(date +%d-%m-%Y)
output=$(sqlplus -S user/pass#service <<EOF
set heading off;
SELECT distinct list_name ,max(captured_dttm) as Last_received FROM db.table1
group by list_name having max(captured_dttm) <= trunc(sysdate - interval '2' hour);
EOF)
if [ -z "$output" ];
then
echo"its fine"
exit
else
echo "
Dear All,
Kindly check we've not received the list for last 2 hour : $output
Regards,
Team" | mailx -S smtp=XX.XX.X.XX:XX -s "URGENT! Please check list FOR $today" user#abc.com
fi
When using a here document, the closing string can't be followed by anything but a newline. Move the closing parenthesis to the next line:
output=$(sqlplus -S user/pass#service <<EOF
...
EOF
)

Using $ notation in middle of C-Shell statement

I have a bunch of directories to process, so I start a for loop like this:
foreach n (1 2 3 4 5 6 7 8)
Then I have a bunch of commands where I am copying over a few files from different places
cp file1 dir$n
cp file2 dir$n
but I have a couple commands where the $n is in the middle of the command like this:
cp -r dir$nstep1 dir$n
When I run this command, the shell complains that it cannot find the variable $nstep1. What i want to do is evaluate the $n first and then concatenate the text around it. I tried using `` and (), but neither of those work. How to do this in csh?
In this respect behavior is similar to POSIX shells:
cp -r "dir${n}step1" "dir${n}"
The quotes prevent string-splitting and glob expansion. To observe what this means, compare the following:
# prints "hello * cruel * world" on one line
set n=" * cruel * "
printf '%s\n' "hello${n}world"
...to this:
# prints "hello" on one line
# ...then a list of files in the current directory each on their own lines
# ...then "cruel" on another line
# ...then a list of files again
# ... and then "world"
set n=" * cruel * "
printf '%s\n' hello${n}world
In real-world cases, correct quoting can thus be the difference between deleting the oddly-named file you're trying to operate on, and deleting everything else in the directory as well.

Output perl results into file

I have a perl script that works fine when I run it using perl filename, however when I use the command
perl -w logint > logintime.html
I get this error
Use of uninitialized value $days in multiplication (*) at logint line 5, <LAST> line 3.
It repeats this from line 3-47
This is the perl code
#!/usr/bin/perl
open LAST, "last |";
while (<LAST>) {
if (($name,$days,$hours,$mins) = /^(\w+).+\((?:(\d+)\+)?(\d+):(\d+)/) {
$TIMES{$name} += 1440 * $days + 60 * $hours + $mins;
}
}
foreach (sort keys %TIMES) {
print "$_ $TIMES{$_}\n";
}
This is how I'm attempting to output it.
#!/bin/bash
echo $HDR > ~/public_html/logintime.html
perl -w logint > logintime.html
echo $FTR >> ~/public_html/logintime.html
This is just a warning, it's not an error. You're seeing it when you run that command because '-w' is the warnings pragma.
You could also put it at the end of your shebang
#!/usr/bin/perl -w
Or 'use warnings;'. Anyway, the warning is just saying it doesn't have a value. It looks like you're reading the last log to see who last logged in, the output can be different depending on what OS you're on. I would confirm it's working as expected and getting the correct values.
It's also best practice to use 'use strict;'.

Why does an empty string get enclosed within a single quotes in a shell script?

I've written a simple shell script "sample.sh" as below
#!/bin/bash
PARAM1="Parameter1"
PARAM2=\"\"
echo "param1-->[$PARAM1] - param2-->[$PARAM2]"
# sample is a compiled binary that just prints it's command line arugments.
./sample -param1 $PARAM1 -param2 $PARAM2
The script is run with -x option as
bash -x sample.sh
The output which I got is
[tspot#raspberrypi : ~/src/sample]$ bash -x sample.sh
+ PARAM1=Parameter1
+ PARAM2='""'
+ echo 'param1-->[Parameter1] - param2-->[""]'
param1-->[Parameter1] - param2-->[""]
+ ./sample -param1 Parameter1 -param2 '""'
arg[0] - [./sample]
arg[1] - [Parameter1]
arg[2] - [""]
[tspot#raspberrypi : ~/src/sample]$
My doubt is why do we get a single quote surrounding the empty string in -param2 in the below line
+ ./sample -param1 Parameter1 -param2 '""'
I would need the line to be
+ ./sample -param1 Parameter1 -param2 ""
Thanks in Advance. Someone please help me out.
That's just the way bash -x formats things in it's debug output. It's adding the extra ' ' to indicate that the string is literally "" and not an empty string. If you look a few lines below, you can see that ./sample does have the expected output: arg[2] - [""].
The problem is that your variable $PARAM2 is the string "" (literally two double quotes).
For what you want, I think you just need to initialize it with :
PARAM2=""
# Or
PARAM2=''
Both are equivalent here.
FYI, the difference between single ' and double " quotes in Bash, is that you can put variable $foo in double quotes and they will be evaluated, whereas it will show literal $ in single quotes :
$ foo=bar
$ echo ">$foo<"
>bar<
$ echo '>$foo<'
>$foo<

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

Resources