linux bash saved variable is empty - linux

I'm new to shell. I try to get a string in file and use it to make a shortcut link.
tmp/tempfile.tmp
/mnt/sda5
in my test.sh file:
#!/bin/sh
#working just fine!
echo $(cat /tmp/tempfile.tmp | cut -d' ' -f2)
#empty result
USBdev = $(cat /tmp/tempfile.tmp | cut -d' ' -f2)
echo ${USBdev}/
# --making a link
ln -s ${USBdev} $(pwd)/C:
exit 0
why it is empty??
echo ${USBdev} --result is empty!
I'm using this on my openwrt router.
I tried as follow, still empty
echo "$USBdev"
echo "${USBdev%.*}"
SOLUTION:
REMOVE "SPACES" AROUND THE "=", thanks to CDroescher
change
USBdev = $(...)
to (remove spaces)
USBdev=$(...)

You have to add a shebang at the first line https://en.wikipedia.org/wiki/Shebang_(Unix) and make sure that there are no spaces after and before "="
#!/usr/bin/env bash
#working just fine!
echo $(cat /tmp/tempfile.tmp | cut -d' ' -f2)
#empty result
USBdev=$(cat /tmp/tempfile.tmp | cut -d' ' -f2)
echo ${USBdev}/
# --making a link
ln -s ${USBdev} $(pwd)/C:

Related

Unix Script loop through individual variables in a list and execute code

I have been busting my head all day long without coming up with a sucessfull solution.
Setup:
We have Linux RHEL 8.3 and a file, script.sh
There is an enviroment variable set by an application with a dynamic string in it.
export PROGARM_VAR="abc10,def20,ghi30"
The delimiter is always "," and the values inside vary from 1 to 20.
Inside the script I have defined 20 variables which take the values
using "cut" command I take each value and assign it to a variable
var1=$(echo $PROGARM_VAR | cut -f1 -d,)
var2=$(echo $PROGARM_VAR | cut -f2 -d,)
var3=$(echo $PROGARM_VAR | cut -f3 -d,)
var4=$(echo $PROGARM_VAR | cut -f4 -d,)
etc
In our case we will have:
var1="abc10" var2="def20" var3="ghi30" and var4="" which is empty
The loop must take each variable, test if its not empty and execute 10 pages of code using the tested variable. When it reaches an empty variable it should break.
Could you give me a hand please?
Thank you
Just split it with a comma. There are endless possibilities. You could:
10_pages_of_code() { echo "$1"; }
IFS=, read -a -r vars <<<"abc10,def20,ghi30"
for i in "${vars[#]}"; do 10_pages_of_code "$i"; done
or:
printf "%s" "abc10,def20,ghi30" | xargs -n1 -d, bash -c 'echo 10_pages_of_code "$1"' _
A safer code could use readarray instead of read to properly handle newlines in values, but I doubt that matters for you:
IFS= readarray -d , -t vars < <(printf "%s" "abc10,def20,ghi30")
You could also read in a stream up:
while IFS= read -r -d, var || [[ -n "$var" ]]; do
10_pages_of_code "$var"
done < <(printf "%s" "abc10,def20,ghi30")
But still you could do it with cut... just actually write a loop and use an iterator.
i=0
while var=$(printf "%s\n" "$PROGARM_VAR" | cut -f"$i" -d,) && [[ -n "$var" ]]; do
10_pages_of_code "$var"
((i++))
done
or
echo "$PROGRAM_VAR" | tr , \\n | while read var; do
: something with $var
done

Syntax error near unexpected token `fi` - Linux

i am using WSL (Ubuntu) in Windows. i used bash script.sh for the script below:
#! /bin/sh
#################LOAD FILES###################
lead_SNPs=`grep "lead_SNPs" ../prep/files.txt | cut -f2`
bfile=`grep -w "bfile" ../prep/files.txt | cut -f2`
bfile_list=`grep -w "bfile_list" ../prep/files.txt | cut -f2`
r2=`grep "r2" ../prep/parameters.txt | cut -f2`
###############LD###########################
if [ ${bfile} = "NA" ]; then
cat ${bfile_list} | while read line; do
file=${line}
file_n=`echo $file |awk -F '/' '{print $NF}'`
echo 'Calculating LD'
plink --bfile ${file} --r2 --ld-window-kb 1000 --ld-window 999999 --ld-window-r2 ${r2} --ld-snp-list ${lead_SNPs} --out C:/Users/naghm/Desktop/FDSP-github/ld/${file_n}
done
else
file=${bfile}
file_n=`echo $file |awk -F '/' '{print $NF}'`
echo ${file_n}
plink --bfile ${file} --r2 --ld-window-kb 1000 --ld-window 999999 --ld-window-r2 ${r2} --ld-snp-list ${lead_SNPs} --out C:/Users/naghm/Desktop/FDSP-github/ld/${file_n}
fi
but i get this error
Syntax error near unexpected token `fi`
can you correct my code please? i can not understand where i made mistake.
Try to change:
if [ ${bfile} = "NA" ]; then
to
if [ "${bfile}" = "NA" ]; then
I suspect ${bfile} is empty which expanded to:
if [ = "NA" ]; then
in your original line.
The first line in your script doesn't look right.
It should be
#!/bin/sh
or if using bash shell:
#!/bin/bash

A shell script that echo’s the commands output to the terminal

A shell script that echo’s the output of the command to the terminal, so far, it’s only outputting empty space. How can I get the desired result? I've tried echoing the variable itself without any luck so I'm guessing the issue is with the command itself.
Actual result:
~$
Preferable result:
Name N. Name
Name N. Name
Name N. Name
Name N. Name
#! /bin/bash
function ag_students() {
ag_names=$(grep -i ^[A-G] /etc/passwd | cut -d: -f5 /etc/passwd > tmp | echo "$tmp" ;)
echo "$tmp"
}
$ag_students
echo "Here are the names: $tmp"
Source code, with some comments:
#! /bin/bash
function ag_students() {
# grep -i ^[A-G] -> grep -i [a-g] # it is absolutely same but you do not need to hit your [shift] key repeatedly.
# <command> | cut -d: -f5 /etc/passwd
# It is stange for me. From the one point of view you want to handle the output
# of the <command1> using <command2> ("cut" utility).
# From the other side you specified the input file for it (/etc/passwd)
# Look at the "cut --help"
# Thus it should be:
# grep -i ^[a-g] /etc/passwd | cut -d: -f5
# without any additions
# Next: "<command> > <name>" will store its output to the file <name>, not to the variable <name>
# "cut -d: -f5 /etc/passwd > tmp" will store its output to the file "tmp", not to the variable with same name
# finally, because, according above, variable "$tmp" still not initialized,
# "echo "$tmp"" will return the empty string whith is assigned to "ag_names" variable
# ag_names=$(grep -i ^[A-G] /etc/passwd | cut -d: -f5 /etc/passwd > tmp | echo "$tmp" ;)
# The right solution:
ag_names=$(grep -i [a-g] /etc/passwd | cut -d: -f5)
# or simpy
grep -i [a-g] /etc/passwd | cut -d: -f5
# It is unnecessary because previous bunch of command alredy output what you want
# echo "$tmp"
}
# Using dollar sign you are trying to execute command contains in the "ag_students" variable (which is not initialized/empty)
# and executing something empty you will get empty result also
$ag_students
# to execute a function - execute it as any other command:
ag_students
# And if you want to have its result in some variable:
tmp=$(ag_students) # as usual
echo "Here are the names: $tmp"
As conclusion, unrelated to the logic, your script should be:
#!/bin/bash
function ag_students() {
grep -i ^[a-g] /etc/passwd | cut -d: -f5
}
tmp=$(ag_students)
echo "Here are the names: $tmp"

bash shell automatically creating user - adduser

I need to automatically create a user by reading lines of a file that contains username, home directory and full name.
I am new to bash shell scripting and it is very confusing to me.
There is something wrong with my adduser command. It gives the error - adduser: Only one or two names allowed.
following is the full script -
while read line;
do
fieldnumbers=$(echo $line | grep - o " " | wc - l)
username=$(echo $line | cut -d' ' -f 1)
home=$(echo $line | cut -d' ' -f 2)
firstname=$(echo $line | cut -d' ' -f 3)
if [[ "$fieldnumbers" -eq b4 ]]
then
middlename=""
else
middlename=$(echo $line | rev | cut -d' ' -f 2)
lastname=$(echo $line | rev | cut -d' ' -f 1)
password=$(echo pwgen 7 1) #create random password
fullname="$firstname $middlename $lastname"
echo "username is : $username"
sudo adduser --gecos $fullname --disabled-password --home $home $username
echo 'username:$password' | chpasswd
echo "Password is for $username is: $password"
done < users.txt
I am sure that this script is riddled with syntax errors. Please help. my brain is fried.
Always quote your variables unless you deliberately want to split the value into separate words.
sudo adduser --gecos "$fullname" --disabled-password --home "$home" "$username"
Also, you have to use double quotes around strings containing variables, not single quotes, if you want the variables to be expanded.
Difference between single and double quotes in Bash
So this line:
echo 'username:$password' | chpasswd
should be:
echo "username:$password" | chpasswd

Bash Script compare strings and variable in an if statement

I am trying to get a variable to compare to a string, and then do something if it does and go on to the next, but when i look at it in debug mode, the variable just shows up as '' with nothing in it.
#!/bin/bash
echo -e "Enter the name of the document you wish to edit:\c"
read dname
CTYPE= file "$dname" | cut -d\ -f2
echo $CTYPE
VAR="ASCII"
VAR2="cannot"
if [ "$CTYPE" == "$VAR" ]
then
vi $dname
fi
I get this result:
+ VAR=ASCII
+ VAR2=cannot
+ '[' '' == ASCII ']'
Where the '' is empty even though I echod it and see that it is not empty.
I have tried it like these other ways as well, and get the same or similar non working result:
CTYPE= file "$dname" | cut -d\ -f2
if [ "$CTYPE" == "$VAR" ]
ctype= file "$dname" | cut -d\ -f2
if [ $ctype = "ASCII" ]
ctype= file "$dname" | cut -d\ -f2
if [ "$ctype" = "ASCII" ]
ctype= file "$dname" | cut -d\ -f2
if [ "$ctype" == "ASCII" ]
Not sure what I am missing, I've read so many posts I don't know where to go from here. Thank you!
You have an error with CTYPE:
CTYPE=$(file "$dname" | cut -d\ -f2)
You cannot have any spaces between the = and the assignment. Further, you want the return from file "$dname" | cut -d\ -f2 so you will have to enclose it in $() or with backticks.
When you run this command:
d= date
bash does this: set an environment variable d (with the value the empty string) only for the duration of the date command. This is densely documented here.
As David tells you, to capture the outut of a command, you need
d=$(date)

Resources