The |
will take the output of the command on the left and give it to the input of the command on the right. The >
operator will take the output of the command and put it into a file. That means, in your example, by the time it gets to the |
there is no output left; it's all gone into a.txt
. So the sort
on the right operates on an empty string and saves that to b.txt
What you would probably like is to use the tee
command which will both write to a file and stdout like
ls | tee a.txt | sort > b.txt
Though I'm really curious what you're trying to do, since ls
can/will sort things for you as well.
I'm often annoyed by the same thing, and there are a few ways of dealing with it:
Just accept it, sometimes it's not worth spending any time to work around it.
as PSkocik mentioned, you can use e.g. tail -n 5 <(dmesg | grep USB)
Become more adept with your shell's editing capabilities - e.g. in bash (and many other programs that use readline) you can use CtrlA to get to beginning of line, ESCf and ESCb to move forward and back a "word", and Ctrl-XCtrl-E to edit the current line in $EDITOR (e.g. vim
)
There are many more editing commands available and readline
is fully documented in .info files. On a Debian system, install the readline-doc
package. Other distros may include the documentation in the readline package itself or may separate it as Debian does.
I also recommend installing and using pinfo
for a more lynx web-browser-like experience (IMO the GNU info
browser is ghastly and almost unusable). If it's not already in your distro, you can find it at http://pinfo.alioth.debian.org/
readline
also has a vi
mode for editing (the default is an emacs
-like mode), which some people prefer.
In simple cases, you can use quick substitution: e.g. if the last command you entered was:
dmesg | grep -i USB | tail -n 5
then typing ^USB^sda^Enter would result in this being executed:
dmesg | grep -i sda | tail -n 5
For more details on this, see man bash
and search for HISTORY EXPANSION
, especially the section Event Designators
.
and yes, doing this repeatedly also becomes annoying.
- For more complex cases, the best solution is to write a shell script or function that does what you want and run that instead of your long complicated pipeline of commands.
e.g. write a shell script called dmesg-grep
that looks something like this:
#! /bin/bash
# regexp to search for is arg 1. needs to be an extended regexp
# because we're using grep -E aka egrep.
re="$1"
# number of lines to output is optional arg 2 (default 5)
lines=${2:5}
dmesg | grep -iE "$re" | tail -n "$lines"
Then you can just run dmesg-grep usb
or dmesg-grep sda
.
If you do this a lot, make a bin
subdirectory of your home directory and add ~/bin
to your default PATH (e.g. in ~/.bash_profile
or ~/.bashrc
) and save your scripts in there.
Best Answer
Sadly I suspect you'll need to rewrite it. (If you have backups, this is the time to get them out. If not, I would strongly recommend you set up a backup regime for the future. Lots of options available, but off topic for this answer.)
I find that putting executables in a separate directory, and adding that directory to the
PATH
is helpful. This way I don't need to reference the executables by explicit path. My preferred programs directory for personal (private) scripts is"$HOME"/bin
and it can be added to the program search path withPATH="$HOME/bin:$PATH"
. Typically this would be added to the shell startup scripts.bash_profile
and/or.bashrc
.Finally, there's nothing stopping you removing write permission for yourself on all executable programs: