How to pass multiple variables as input in shell script in non-interactive way - linux

I am trying to make this interactive script take inputs in a non-interactive way by declaring $username and $password variables in bash env and pass them as inputs to the script. By running ./input.sh <<< "$username"
#!bin/bash
read username
read password
echo "The Current User Name is $username"
echo " The Password is $password"
is there a way to pass both the variables as input? Because with what I have tried it only takes one input this way.

So, staying as close as possible as your initial try (but I doubt that is the best solution for any real problem), what you are asking is "how I can pass 2 lines with here-string".
A possible answer would be
./input.sh <<< "$username"$'\n'"$password"
here-strings are the construct you are using when using <<<. When you type ./input.sh <<< astring it is, sort-of, the same as if you were typing echo astring | ./input.sh: it use the string as standard input of ./input.sh. Since your reads read lines, you need 2 lines as standard input to achieve what you want. You could have done this that way: (echo "$username" ; echo "$password") | ./input.sh. Or anyway that produces 2 lines, one with $username one with $password and redirecting those 2 lines as standard input of ./input.sh
But with here-string, you can't just split in lines... Unless you introduce explicitly a carriage return (\n in c notation) in your input string. Which I do here using $'...' notations, that allows c escaping.
Edit. For fun, I include here the other solutions I wrote in comments, since you are not specially requiring here-strings.
(echo "$username" ; echo "$password") | ./input.sh
{echo "$username" ; echo "$password" ; } | ./input.sh
printf "%s\n" "$username" "$password" | ./input.sh
./input.sh < <(echo "$username" "$password")
./input.sh < <(printf "%s\n" "$username" "$password")
Plus of course solutions that changes ./input.sh
#!bin/bash
username="$1"
password="$2"
echo "The Current User Name is $username"
echo " The Password is $password"
called with ./input "$username" "$password"
Or
#!bin/bash
echo "The Current User Name is $username"
echo " The Password is $password"
called with username="$username" password="$password" ./input.sh

Easiest way would be something like that:
#!/bin/bash
echo "The Current User Name is $1"
echo "The Password is $2"
$1 represents the first given argument and $2 the second.
[user#vm ~]$ input.sh "user" "password"
Inside the quotation marks ("") put the argument you want to pass.
For more professional/robust solution check this out: Redhat: Bash Script Options/Arguments

Related

Brute force bash script with another bash script

so i currently have a bash script that takes a hash value and then asks the user to input a password, converts their input to hash and then compares.
#!/bin/bash
crypt="8277e0910d750195b448797616e091ad"
echo "please enter a password!"
read inc
hash="$((echo -n $inc|md5sum) | awk '{print $1}')"
if [[ "$hash" == "$crypt" ]];
then
echo "logged in"
else
echo "incorrect pass"
fi
I now want to create another program that brute forces this password by adding values(from a-z) into the password input but im running into trouble as i feel my knowledge on bash file manipulation is limited as ive never ran a script against another script before.
#!/bin/bash
for i in {a..z}; do
(echo -n "$i: " && ./hashscript $i) | grep logged in
done
Since the 1st script is reading the data from stdin (with read), the 2nd script will need to pass the data in that way:
#!/bin/bash
for i in {a..z}; do
(echo -n "$i: " && echo $i | ./hashscript) | grep logged in
done

Unable to array values outside of function in shell script [duplicate]

Please explain to me why the very last echo statement is blank? I expect that XCODE is incremented in the while loop to a value of 1:
#!/bin/bash
OUTPUT="name1 ip ip status" # normally output of another command with multi line output
if [ -z "$OUTPUT" ]
then
echo "Status WARN: No messages from SMcli"
exit $STATE_WARNING
else
echo "$OUTPUT"|while read NAME IP1 IP2 STATUS
do
if [ "$STATUS" != "Optimal" ]
then
echo "CRIT: $NAME - $STATUS"
echo $((++XCODE))
else
echo "OK: $NAME - $STATUS"
fi
done
fi
echo $XCODE
I've tried using the following statement instead of the ++XCODE method
XCODE=`expr $XCODE + 1`
and it too won't print outside of the while statement. I think I'm missing something about variable scope here, but the ol' man page isn't showing it to me.
Because you're piping into the while loop, a sub-shell is created to run the while loop.
Now this child process has its own copy of the environment and can't pass any
variables back to its parent (as in any unix process).
Therefore you'll need to restructure so that you're not piping into the loop.
Alternatively you could run in a function, for example, and echo the value you
want returned from the sub-process.
http://tldp.org/LDP/abs/html/subshells.html#SUBSHELL
The problem is that processes put together with a pipe are executed in subshells (and therefore have their own environment). Whatever happens within the while does not affect anything outside of the pipe.
Your specific example can be solved by rewriting the pipe to
while ... do ... done <<< "$OUTPUT"
or perhaps
while ... do ... done < <(echo "$OUTPUT")
This should work as well (because echo and while are in same subshell):
#!/bin/bash
cat /tmp/randomFile | (while read line
do
LINE="$LINE $line"
done && echo $LINE )
One more option:
#!/bin/bash
cat /some/file | while read line
do
var="abc"
echo $var | xsel -i -p # redirect stdin to the X primary selection
done
var=$(xsel -o -p) # redirect back to stdout
echo $var
EDIT:
Here, xsel is a requirement (install it).
Alternatively, you can use xclip:
xclip -i -selection clipboard
instead of
xsel -i -p
I got around this when I was making my own little du:
ls -l | sed '/total/d ; s/ */\t/g' | cut -f 5 |
( SUM=0; while read SIZE; do SUM=$(($SUM+$SIZE)); done; echo "$(($SUM/1024/1024/1024))GB" )
The point is that I make a subshell with ( ) containing my SUM variable and the while, but I pipe into the whole ( ) instead of into the while itself, which avoids the gotcha.
#!/bin/bash
OUTPUT="name1 ip ip status"
+export XCODE=0;
if [ -z "$OUTPUT" ]
----
echo "CRIT: $NAME - $STATUS"
- echo $((++XCODE))
+ export XCODE=$(( $XCODE + 1 ))
else
echo $XCODE
see if those changes help
Another option is to output the results into a file from the subshell and then read it in the parent shell. something like
#!/bin/bash
EXPORTFILE=/tmp/exportfile${RANDOM}
cat /tmp/randomFile | while read line
do
LINE="$LINE $line"
echo $LINE > $EXPORTFILE
done
LINE=$(cat $EXPORTFILE)

Beginner's Bash Scripting: "Unary Operator Expected" error && how to use grep to search for a variable from the output of a command?

I'm attempting to write a bash script that is executed through "./filename username" and checks whether or not that user is logged in, printing the result. I'm still new to scripting and am having trouble understanding how to make this work.
I'm currently getting the error "line 7: [: ambonill: unary operator expected". What does that mean and how can I go about fixing that error?
Additionally, how would I get grep to work instead of sort | uniq? I'd like to grep for the variable from the output of the command but can't find anything related in the man page.
#! /bin/bash
# This script will take a username as an argument and determine whether they are logged on.
function loggedin {
for u in `who | cut -f1 -d" " | sort | uniq`
do
if [ $u == $1 ]
then
echo "$1 is logged on"
else
echo "$1 is not logged on"
fi
exit 0
done
}
loggedin $u
exit 1
Try to find a simpler solution, like:
#!/bin/bash
echo "$1 is $([ -z "$(w -h $1)" ]&&echo -n not\ )logged on"

In Bash, how can I output a new line after read -es?

current code:
echo -n "password: "
read -es password
echo -n "ok"
behavoir in linux:
password: ok
Can we make it like:
password:
ok
thanks,
wxie
The following will work:
read -p "password: " -es password
echo
echo "ok"
Maybe:
read -p "password: " -es password
printf "\n ok \n"
If you want a newline before the OK, this should do it:
echo -e "\nok"
The -e enables interpretation of the backslash codes.
From echo's man page: -n do not output the trailing newline. Try it without the option.
We can use \n as a line separator in printf, there is an extra line for padding after "ok" which you can remove
printf "password: " && read -es password && printf "\n\nok\n"
If you are saving a password this way it would still be contained in the variable $password in plain text, the string below would print it openly.
printf "$password"
Your code sample uses echo and should be using printf, there are articles on echo's POSIX compliance, echo could work like Greg Tarsa points out, but not all versions are built with switch options like -e or -n.
I find it readable to use printf, also other "languages" have similar commands such as PRINT, print, println, print() and others.
If you need to use echo you could
echo -n "password: " && read -es password && echo -e "\nok\n"

Add user account from file script error [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Linux Script Extract Information From Excel To Create Users
Need to create users from excel spread sheet, getting a few errors in my script on lines 8 and 13
Line 8 Unexpected EOF while looking for matching `''
Line 13 Syntax error unexpected end of file
#!bin/bash
echo $(pwd)/employeesdata.xls
Path=$($pwd)/employeesdata.xls
read Path
if [ -e $Path ];
then
Username= [ grep $(Username) $Path | cut -f1 -d `]'
Password= [ grep $(Password) $Path | cut -f2 -d `]'
useradd -- b $Username
echo $Password | /usr/bin/passwd --stdin $Username
fi
exit
Excel file has this and other information
Name (field1) EmployeeID (field2) Phone Address
Joe Blow 22500033 156-454-3322 101 main
I think you'd have to refactor a few things:
#!bin/bash
echo $(pwd)/employeesdata.xls
Path="$(pwd)/employeesdata.xls"
read Path
if [ -e "$Path" ]; then
Username=$(grep "$Username" "$Path" | cut -f1 -d ' ')
Password=$(grep "$Password" "$Path" | cut -f2 -d ' ')
useradd -- b $Username
echo "$Password" | /usr/bin/passwd --stdin "$Username"
fi
exit
A few notes:
Quote the value you are assigning to a variable (sometimes this is not necessary, but for starting out it helps to avoid some problems)
Quote the usage of a variable, unless you know what you're doing. Without quoting it explicitly, the variable can generate various parameters to commands/functions.
$(cmd) executes the command cmd and replaces its occurrence with the output of the command.
$var or ${var} replaces itself with the contents of variable named var
"quoting $a", supposing the variable a contains string as its contents, generates the string quoting string.
'quoting $a', independent of the variable a, generates the string quoting $a.
As confusing as it can be for newcomers, [ is actually an "alias" for the test command, which can be used to compare strings, integers, and do some basic tests like checking the permissions or the existence of a file. ] is actually just a syntax requirement just to inform the command that its parameters have ended (when called .
I assumed your delimiter is a space, but I could be wrong.
Hope this helps a little =)

Resources