tee command creates empty file - bash

Hi I have the following list of stocks that is generated and it is placed in file called awk_1
dfs
fsd
dsf
sdf
I then run the following one liner which generates the correct ULR links
while read i ; do
echo $(http://uk.finance.yahoo.com/echartss=$i#symbol=$i\;range=my\;compare=\;indicator=volume\;charttype\=area\;crosshair\=on\;ohlcvalues\=0\;logscale\=off\;source\=undefined\;) tee stock_urls;
done < awk_1
However is does not put the out put in the file called stock_urls ?
Also it generate and strange output on the screen, below is a small section of the output that I get to standard output. It puts "./large_cap_stocks.sh: 51: ./large_cap_stocks.sh:" at the front and "not found" at the end , why might that be happening.
I have searching high and low for why this is not working any help would be really appreciated.
Thanks

You probably meant to write like this:
while read i; do
echo "http://uk.finance.yahoo.com/echarts?s=$i#symbol=$i\;range=my\;compare=\;indicator=volume\;charttype\=area\;crosshair\=on\;ohlcvalues\=0\;logscale\=off\;source\=undefined\;"
done < awk_1 | tee stock_urls
That is:
In the echo command, use "..." to quote your text instead of $(...) which is something else
Use the pipe operator | to pass the output to tee, and you can pipe the entire loop this way, no need to do for individual echo lines.

Related

How to append output in bash?

I have a shell command that produces line based output. Let me call it magic for the sake of the argument. For whatever output it produces, how can I just append another value to it? I would like to do it in a pipe. I tried for a long time to google this without any luck. It seems like I must be missing some obvious way to do it. Ideally, there would be another unix command called append which given as standard input the output of any other command the same output along with its arguments.
What I am imagining:
magic
This returns:
apple
cherry
banana
magic | append taro
This returns:
apple
cherry
banana
taro
Does this append command already exist with a different name? If so, what is it called?
Converting my comment to answer so that solution is easy to find for future visitors.
You may use grouping of command using { ...; } to group multiple commands:
{ magic; echo 'taro'; }
And if you want to redirect output to a file then use:
{ magic; echo 'taro'; } > outfile
The best way is not to use a pipe, but anubhava's { magic; echo 'taro'; }.
However, since you asked a pipe, you've opened up Pandora's box of possibilities.
magic|sed '$ataro'
is the first.
magic| awk '{print} END{print "taro"}'
as second.
Or a bash function:
hop(){
while read line; do
echo $line
done
echo $1
}
magic | hop taro
And so on.

it only display a number "2" when using while read line to redirect the content of one file to another

The content of the script is:
#!/bin/bash
tempconf="/tmp/test.file"
while read line
do
echo $line
done < test.conf > $tempconf
The content of the test.conf is:
[PORT]
tcp_ports=7000-7200
udp_ports=7000-8000, 40000-49999
[H323H]
maxSendThreads=10
maxRecvThreads=10
[SDK]
appPwd=1111111
amsAddress=192.168.222.208:8888
The content of the output file "/tmp/test.file" is:
[PORT]
tcp_ports=7000-7200
udp_ports=7000-8000, 40000-49999
2
maxSendThreads=10
maxRecvThreads=10
[SDK]
appPwd=1111111
amsAddress=192.168.222.208:8888
The question is,why [H323H] turns out to be 2. I'll be appreciated if anyone can explain it to me.
[] has a special meaning for the shell, it just means "a single character taken from any of the characters between the brackets". So when you run
echo [H323H]
the shell looks for a file named or H, or 2, or 3... If at least one file matches, [H323H] is replaced with all the matching file names in the output; otherwise it's reproduced as is.
source: https://unix.stackexchange.com/a/259385
Using quotes around $line would solve your problem without the need to check for files matching those characters (which would make the script not very robust)
#!/bin/bash
tempconf="/tmp/test.file"
while read -r line
do
echo "$line"
done < test.conf > "$tempconf"

How can I access a file in bash and compare its contents with stdout when running a program to make sure they are identical?

How can I to compare the output in stdout of a program with a model output in an output file? I ask because I am trying to make a grading script. Also, I am thinking of using -q grep, but am not sure how I would use it still.
Please make answer simple because I am a noob at bash.
Important edit:
I want to use this in an if statement. For example:
if(modle_file.txt is identical to stdout when running program); then
echo "Great!"
else
echo "Wrong output. You loose 1 point."
Edit:
The program takes an input. So for example if we do:
%Python3 Program.py
Enter a number: 5
The first 5 (arbitrary) things are:
2, 5, etc (program output)
%
If your file is called example.txt, do
diff example.txt <(program with all its options)
The <() syntax takes the output of the program in parentheses and passes it to the diff command as if it was a text file.
EDIT:
If you just want to check whether the text file and the output of the program are the same or not in an if-clause, you can do:
if [ "$(diff example.txt <(program with all its options))" == "" ]; then
echo 'the outputs are identical'
else
echo 'the outputs differ'
fi
I.e. diff only generates output if the files differ, so an empty string as answer means the files are identical.
EDIT 2:
In principle you can re-direct stdin to a file, like so:
program < input.txt
Now, without further testing, I don't know whether this will work with your python script, but suppose you can put all the input the program expects into such a file, you could do
if [ "$(diff example.txt <(program < input.txt))" == "" ]; then
echo 'Great!'
else
echo 'Wrong output. You loose 1 point.'
fi
EDIT 3::
I wrote a simple test program in python (let's call it program.py):
x = input('type a number: ')
print(x)
y = input('type another number: ')
print(y)
If you run it interactively in the shell with python program.py, and give 5 and 7 as answers, you get the following output:
type a number: 5
5
type another number: 7
7
If you create a file, say input.txt, which contains all the desired input,
5
7
and pipe that into your file like so:
python program.py < input.txt
you get the following output:
type a number: 5
type another number: 7
The reason for the difference is that python (and many other shell programs) treat input differently depending on whether it comes from an interactive shell, a pipe, or a redirected stdin. In this case, input is not echoed as the input comes from input.txt. However, if you run both your code and the student's code using input.txt, the two outputs should still be comparable.
EDIT 4:
As one of the comments states below, it is not necessary to compare the entire output of the diff command against an empty string ("") if you only want to know whether they differ, the return status is enough. It's best to write a small test script in bash (let's call it code_checker.sh),
if diff example.txt <(python program.py < input.txt) > /dev/null; then
echo "Great!"
else
echo "Wrong output. You loose 1 point."
fi
the >/dev/null part in the if-clause re-directs the output of diff to a special device, effectively ignoring it. If you have a lot of output, it might be better to use cmp like mentioned by user1934428.
One way to do this would be to redirect the stdout output to a file, like this:
myCommand > /folder/file.txt
And then run a diff command to compare the two files
diff /folder/file.txt /folder/model_output.txt
Edit: To use this on an if statement, you could do the following:
if [ -z "$(diff /folder/file.txt /folder/model_output.txt 2>&1)" ]; then echo "Great!"; else echo "Wrong output. You loose 1 point."; fi
If the files are equal, it will print Great!, otherwise it will print Wrong output. You loose 1 point.
Since you are not interested in the actual differences, but only in whether they are identical, I think cmp is the best choice (and faster if the files are large):
if cmp -s example.txt <(your program goes here)
then
echo identical
fi
Note that this compares only stdout (as you requested), not stderr.

Bash Script IF statement not functioning

I am currently testing a simple dictionary attack using bash scripts. I have encoded my password "Snake" with sha256sum by simply typing the following command:
echo -n Snake | sha256sum
This produced the following:
aaa73ac7721342eac5212f15feb2d5f7631e28222d8b79ffa835def1b81ff620 *-
I then copy pasted the hashed string into the program, but the script is not doing what is intended to do. The script is (Note that I have created a test dictionary text file which only contains 6 lines):
echo "Enter:"
read value
cat dict.txt | while read line1
do
atax=$(echo -n "$line1" | sha256sum)
if [[ "$atax" == "$value" ]];
then
echo "Cracked: $line1"
exit 1
fi
echo "Trying: $line1"
done
Result:
Trying: Dog
Trying: Cat
Trying: Rabbit
Trying: Hamster
Trying: Goldfish
Trying: Snake
The code should display "Cracked: Snake" and terminate, when it compares the hashed string with the word "Snake". Where am I going wrong?
EDIT: The bug was indeed the DOS lines in my textfile. I made a unix file and the checksums matched. Thanks everyone.
One problem is that, as pakistanprogrammerclub points out, you're never initializing name (as opposed to line1).
Another problem is that sha256sum does not just print out the checksum, but also *- (meaning "I read the file from standard input in binary mode").
I'm not sure if there's a clean way to get just the checksum — probably there is, but I can't find it — but you can at least write something like this:
atax=$(echo -n "$name" | sha256sum | sed 's/ .*//')
(using sed to strip off everything from the space onwards).
couple issues - the variable name is not set anywhere - do you mean value? Also better form to use redirection instead of cat
while read ...; do ... done <dict.txt
Variables set by a while loop in a pipeline are not available in the parent shell not the other way around as I mistakenly said before - it's not an issue here though
Could be a cut n paste error - add an echo after the first read
echo "value \"$value\""
also after atax is set
echo "line1 \"$line1\" atax \"$atax\""

Weird characters when I print a number into a file (bash shell)

I have this line in my script.sh
printf "%d" "$endMS_line"
$endMS_line is a number. I get that number with
endMS_line=`cat file | awk '{if($1=='"$variable"') print NR}'`
And to print it I use
printf "%d" "$endMS_line"
or
echo $endMS_line
So everything works perfectly in the standard output. The problem is when I want to save that number into a file (because I want to use the result in another script, may be there is a clever way to do it than write a file and then read the number from the file, etc..)
But for now I am trying to do that. How? Well I write this in the standard output.
myscript.sh inputs > file.txt
But when I try to see the file (when I open the file) I see the result plus weird characteres
[H[2J867
The correct number in this example is 867. Anyone know how can I fix this?
Thank you!
At the begginning of the script I had the command:
clear
removing that and using:
echo "$endMS_line"
Then in the standard output:
myscript.sh input > file.txt
works perfectly.

Resources