Can anyone help me out with the following code snippet -
echo Start|cat>>log
When I tried
echo Start>>log
it gave the same output to the log file. Can anyone explain the difference between the two commands?
cat is one of those programs that can take an argument and use it, or just use its standard input if you don't provide an argument. In other words, while:
cat xyzzy
will open the file xyzzy and output its contents, the command:
cat
on its own will read its standard input and send that to standard output.
Hence piping some output through cat without an argument is no different that just sending the output without cat, other than creating a superfluous process. In other words, these two are functionally identical:
echo xyzzy | cat
echo xyzzy
You can use either but the latter (for both my example above and in your question) will use one less process and a few less keystrokes. The cat filter on its own will simply pass the data through as-is and hence is not necessary.
Related
Just to give a quick example:
~$ cd ~/Documents/
~$ ls
a file another file
~$ echo “Ok”
Ok
~$ rm *
~$ ls
~$ cd
This is inspired by this question, where trap 'echo' DEBUG is used to add an empty line before and after the output of every command. Unfortunately, empty lines are still added if the command had no output. Another downside of trap 'echo' DEBUG is that it is a bit ‘hacky’ and I’ve heard of it breaking some programs. It also adds empty lines between the output of commands in a pipe.
Now, I realise that it may not be possible to add an empty line before the output of a command because, to check if the command has any output, the output has to first be printed to the screen, and then you can’t add the empty line! Because of this it would also be OK if there’s an empty line between each prompt when running a command without output, just not that there’s two lines, like with trap 'echo' DEBUG.
The reason I’m doing this is I often find it difficult to find my prompt in a sea of output, especially when it is a colourful diff. I have tried two-line prompts, sometimes with empty lines before, and also adding a hideous mess of colours to my prompt. Neither has been quite satisfactory.
Thanks for the help!
You can simply do:
echo ""
Although for formatted outputs ending with a new line, printf is a better choice, for example :
printf "%s\n\n" "output"
I think the following thread is on your topic, for empty lines:
What is the preferred method to echo a blank line in a shell script?
As for controling the output try placing the command execution inside a variable and then evaluate the way you want.
For example with ls and if:
list=$(ls | wc -l)
if [ "$list" -gt 0 ]
then
echo "Working fine"
else
echo ""
fi
You can still print the output of the comand if you need to. But I think it is not necessary if there isn't some kind of reporting involved.
For example to print the output in both cases:
Add the following to both when the condition is fulfilled and when it is not (execution of the command again):
echo "$(ls)"
For example altering the condition to not fulfill it gets the desired output:
adama#galactica:~$ ./processing.sh
a
column2.txt
pepito
processing.sh
test.txt
Best Regards
I am trying to read contents of a file given from standard input into a script. Any ideas how to do that?
Basically what I want is:
someScript.ksh < textFile.txt
Inside the ksh, I am using a binary which will read data from "textFile.txt" if the file is given on the standard input.
Any ideas how do I "pass" the contents of the given input file, if any, to another binary inside the script?
You haven't really given us enough information to answer the question, but here are a few ideas.
If you have a script that you want to accept data on stdin, and that script calls something else that expects data to be passed in as a filename on the command line, you can take stdin and dump it to a temporary file. Something like:
#!/bin/sh
tmpfile=$(mktemp tmpXXXXXX)
cat > $tmpfile
/some/other/command $tmpfile
rm -f $tmpfile
(In practice, you would probably use trap to clean up the temporary file on exit).
If instead the script is calling another command that also expects input on stdin, you don't really have to do anything special. Inside your script, stdin of anything you call will be connected to stdin of the calling script, and as long as you haven't previously consumed the input you should be all set.
E.g., given a script like this:
#!/bin/sh
sed s/hello/goodbye/
I can run:
echo hello world | sh myscript.sh
And get:
goodbye world
I'm writing a bash script called 'run' that tests programs with pre-defined inputs.
It takes in a file as the first parameter, then a program as a second parameter.
The call would look like
./run text.txt ./check
for example, the program 'run' would run 'check' with text.txt as the input. This will save me lots of testing time with my programs.
right now I have
$2 < text.txt > text.created
So it takes the text.txt and redirects it as input in to the program specified, which is the second argument. Then dumps the result in text.created.
I have the input in text.txt and I know what the output should look like, but when I cat text.created, it's empty.
Does anybody know the proper way to run a program with a file as the input? This seems intuitive to me, but could there be something wrong with the 'check' program rather than what I'm doing in the 'run' script?
Thanks! Any help is always appreciated!
EDIT: the file text.txt contains multiple lines of files that each have an input for the program 'check'.
That is, text.txt could contain
asdf1.txt
asdf2.txt
asdf3.txt
I want to test check with each file asdf1.txt, asdf2.txt, asdf3.txt.
A simple test with
#!/bin/sh
# the whole loop reads $1 line by line
while read
do
# run $2 with the contents of the file that is in the line just read
xargs < $REPLY $2
done < $1
works fine. Call that file "run" and run it with
./run text.txt ./check
I get the program ./check executed with text.txt as the parameters. Don't forget to chmod +x run to make it executable.
This is the sample check program that I use:
#!/bin/sh
echo "This is check with parameters $1 and $2"
Which prints the given parameters.
My file text.txt is:
textfile1.txt
textfile2.txt
textfile3.txt
textfile4.txt
and the files textfile1.txt, ... contain one line each for every instance of "check", for example:
lets go
or
one two
The output:
$ ./run text.txt ./check
This is check with parameters lets and go
This is check with parameters one and two
This is check with parameters uno and dos
This is check with parameters eins and zwei
The < operator redirects the contents of the file to the standard input of the program. This is not the same as using the file's contents for the arguments of the file--which seems to be what you want. For that do
./program $(cat file.txt)
in bash (or in plain old /bin/sh, use
./program `cat file.txt`
).
This won't manage multiple lines as separate invocations, which your edit indicates is desired. For that you probably going to what some kind scripting language (perl, awk, python...) which makes parsing a file linewise easy.
I've written a small script in bash that parses either the provided files or stdin if no file is given to produce some output. What is the best way to redirect the parsed output to stdout (at the end of the script the result is stored in a variable). Should I use cat or echo, or is there another preferred method?
Use the printf command:
printf '%s\n' "$var"
echo is ok for simple cases, but it can behave oddly for certain arguments. For example, echo has a -n option that tells it not to print a newline. If $var happens to be -n, then
echo "$var"
won't print anything. And there are a number of different versions of echo (either built into various shells or as /bin/echo) with subtly different behaviors.
echo. You have your parsed data in a variable, so just echo "$var" should be fine. cat is used to print the contents of files, which isn't what you want here.
echo is a fine way to do it. You will have to jump through a few hoops if you want cat to work.
i have a file called test which contains the word "hello" in it.
shouldn't
echo test | cat
output hello? since its taking the output from the echo test, which is test, as the input for cat. so essentially im doing cat test.
but the actual output is test, im really confused.
Your pipes sends test to cat as the input, not as the argument. You could do:
cat `echo test`
to control the argument to cat with echo.
echo prints its arguments. cat prints a file which is by default standard input. When you pipe echo's standard output is connected to cat's standard input.
Correct is simply cat test.
From cat --help
If no FILE or when FILE is -, read standard input.
In your case, cat reads from stdin, which is test and outputs that.
In some cases you might want the argument to be passed through the pipe. This is how you would do that:
echo test | xargs cat
which will output the contents of the file named "test".