Redirect to a file which is got from command line - shell

I'm a beginner. :)
I'm trying to ask the name of file from prompt in a shell
and edit that file in another shell like this:
test.sh
echo "enter file name"
read word
sh test2.sh
test2.sh
read number
echo "$number" >> $word
I get an error
Test2.sh: line 1: $mAmbiguous redirect
Any suggestion?

If you want a variable from test.sh to be visible to its child processes, you need to export it. In your case, you would seem to want to export word. Perhaps a better approach would be for test2.sh to accept the destination file as a parameter instead, though.
test.sh
echo "enter file name"
read word
test2.sh "$word"
test2.sh
#!/bin/sh
: ${1?must have destination file name} # fail if missing
read number
echo "$number" >> "$1"

Related

Bash Scripting - User Input a Command

Very easy question but I really can't find this when I Google. Sorry!
I'm trying to write a script that runs a user's command that he or she enters but I can't run the command that the user enters.
#!/bin/bash
echo -e "Enter a Command: "
read $COMMAND
echo "Output: $COMMAND" # I can't figure how to implement and print the command
Enter a Command: ls
Output: folder1 folder2 folder3 test.txt)
All you need is to delete the dollar sign from the read command
#!/bin/bash
echo "Enter a Command: "
read COMMAND
echo "Output: $COMMAND"
Happy scripting!, please don't forget to marked as answered ;)
Use eval to execute a command from a variable.
Also, you don't put $ before the variable name in the read command. That's only used when you want to get the variable's value.
#!/bin/bash
echo -e "Enter a Command: "
read COMMAND
echo Output:
eval "$COMMAND"
DEMO
Thanks! This answered my question:
#!/bin/bash
echo -e "Enter a Command: "
read COMMAND
echo Output:
eval "$COMMAND"

Read from executable and write back response

I'm starting an executable with
./test
It will then write a text to stdout
static test: DYNAMIC_VAL
The static test is always the same but the value DYNAMIC_VAL changes.
I need to read DYNAMIC_VAL, process it and send back byte hex codes \x12\x34\x56 to the stdin depending on DYNAMIC_VAL.
./test is an executable and the stdin should be performed to the original invocation of test, otherwise the DYNAMIC_VAL would have changed with a new invocation.
Is there a simple way of doing this in bash?
If I'm understanding this question correctly, you want to read a line from your ./test process, and write data back to the same process and repeat until it produces something saying it's done (Or forever)?
One way is to use a coprocess.
Example:
$ cat test.sh
#!/bin/sh
echo "static test: foo"
read line
echo "static test: bar"
read line
echo "static test: done"
$ cat demo.sh
#!/usr/bin/env bash
coproc ./test.sh
while true; do
read -r -u "${COPROC[0]}" s t dynamic_val
case "$dynamic_val" in
"done")
echo "Exiting"
break;;
*)
echo "read $dynamic_val"
printf "\x12\x34\x56\n" >&"${COPROC[1]}";;
esac
done
$ ./demo.sh
read foo
read bar
Exiting

Read from .txt file containing executable commands to be executed w/ output of commands executed sent to another file

When I run my script, the .txt file is read, the executable commands are assigned to $eggs, then to execute the commands and redirect the output to a file I use echo $eggs>>eggsfile.txt but when I cat the file, I just see all the commands and not the execution output of those commands.
echo "Hi, $USER"
cd ~/mydata
echo -e "Please enter the name of commands file:/s"
read fname
if [ -z "$fname" ]
then
exit
fi
terminal=`tty`
exec < $fname #exec destroys current shell, opens up new shell process where FD0 (STDIN) input comes from file fname
count=1
while read line
do
echo $count.$line #count line numbers
count=`expr $count + 1`; eggs="${line#[[:digit:]]*}";
touch ~/mydata/eggsfile.txt; echo $eggs>>eggsfile.txt; echo "Reading eggsfile contents: $(cat eggsfile.txt)"
done
exec < $terminal
If you just want to execute the commands, and log the command name before each command, you can use 'sh -x'. You will get '+ command' before each command.
sh -x commands
+pwd
/home/user
+ date
Sat Apr 4 21:15:03 IDT 2020
If you want to build you own (custom formatting, etc), you will have to force execution of each command. Something like:
cd ~/mydata
count=0
while read line ; do
count=$((count+1))
echo "$count.$line"
eggs="${line#[[:digit:]]*}"
echo "$eggs" >> eggsfile.txt
# Execute the line.
($line) >> eggsfile.txt
done < $fname
Note that this approach uses local redirection for the while loop, avoiding having to revert the input back to the terminal.

How do I programmatically execute a carriage return in bash?

My main file is main.sh:
cd a_folder
echo "executing another script"
source anotherscript.sh
cd ..
#some other operations.
anotherscript.sh:
pause(){
read -p "$*"
}
echo "enter a number: "
read number
#some operation
pause "Press enter to continue..."
I wanted to skip the pause command. But when I do:
echo "/n" | source anotherscript.sh
It doesn't allow to enter the number. I want the "/n" to occur so that I allow the user to enter a number but skip the pause statement.
PS: can't do any changes in anotherscript.sh. All changes to be done in main.sh.
Try
echo | source anotherscript.sh
Your approach does not work, because the script to be sourced expectes two lines from stdin: First a line containing a number, then an empty line (which is doing the pause). Hence you would have to feed two lines, the number and the empty line, to the script. If you still want to get the number from your own stdin, you would have to use a read command before:
echo "executing another script"
echo "enter a number: "
read number
printf "$number\n\n" | source anotherscript.sh
But this still has some danger lurking: The source command is executed in a subshell; hence, any changes in the environment performed by anotherscript.sh won't be visible in your shell.
A workaround would be to be to put the number-reading logic outside of main.sh:
# This is script supermain.sh
echo "executing another script"
echo "enter a number: "
read number
printf "$number\n\n"|bash main.sh
where in main.sh, you simply keep your source anotherscript.sh without any piping.
As user1934428 comments, the bash pipeline causes the cascading
commands to be executed in subshells and the variable modifications
there are not reflected in the current process.
To change this behavior, you can set lastpipe with shopt builtin.
Then bash changes the job control so that the last command in the
pipeline is executed in the current shell (as tsch does).
Then would you please try:
main_sh
#!/bin/bash
shopt -s lastpipe # this changes the job control
read -p "enter a number: " x # ask for the number in main_sh instead
cd a_folder
echo "executing another script"
echo "$x" | source anotherscript.sh > /dev/null
# anotherscript.sh is executed in the current process
# unnecessary messages are redirected to /dev/null
cd ..
echo "you entered $number" # check the result
#some other operations.
which will properly print the value of number.
Alternatively you can also say as:
#!/bin/bash
read -p "enter a number: " x
cd a_folder
echo "executing another script"
source anotherscript.sh <<< "$x" > /dev/null
cd ..
echo "you entered $number"
#some other operations.

How to get input from command line in a simple bash file?

I think this is the worst error I have ever seen. I have written what I have seen also here:
Example of script but continuously I get error. My plan is to see how read command works. But it seems a dodgy error in my code or terminal. I wondered if anyone has seen similar problem?
#!/usr/bin/bash
echo "Plz enter"
read text
echo "You entered $text"
echo $text
echo "$text"
Error:
$ . test.sh
Plz enter
b
': not a valid identifier
You entered
$
Yes I had the same error in windows with cygwin, I fixed it changing the end of line format from windows format to unix format.
You can also convert the end of line format using Notepad++: Edit > EOL Conversion > UNIX, then save and run the file.
Your input file contains CR+LF line endings.
Remove those and the script should work well. You could use dos2unix or any other utility to remove the CR.
I think, try to change the shell path as like below!
root#sathish:/tmp# vim test.sh
#!/usr/bin/bash
echo "Plz enter"
read text
echo "You entered $text"
echo $text
echo "$text"
root#sathish:/tmp# chmod +x test.sh
root#sathish:/tmp# ./test.sh
-bash: ./test.sh: /usr/bin/bash: bad interpreter: No such file or directory
root#sathish:/tmp# which bash
/bin/bash
root#sathish:/tmp# ls /usr/bin/bash
ls: cannot access /usr/bin/bash: No such file or directory
root#sathish:/tmp# vim test.sh
#!/bin/bash
echo "Plz enter"
read text
echo "You entered $text"
echo $text
echo "$text"
root#sathish:/tmp# ./test.sh
Plz enter
a
You entered a
a
a

Resources