"Everything is a file" describes one of the defining features of Unix and its derivatives — that a wide range of input/output resources such as documents, directories, hard-drives, modems, keyboards, printers and even some inter-process and network communications are simple streams of bytes exposed through the filesystem name space.
stdin, stdout, stderr
When you type commands into the shell, you are sending a stream of characters into a file-like entity called Standard In (stdin) that is attached to the actual shell program. The shell parses and executes the command, then sends the resulting output into a similar entity called Standard Out (stdout), which prints the results on your terminal. Any error messages are directed to Standard Error (stderr) which is also connected to the terminal.
Let's look at an example.
pi@raspberrypi:~/work $ ls
dir1 dir2 file1 hello.py testfile testfile1
pi@raspberrypi:~/work $ ls > testfile1
pi@raspberrypi:~/work $ cat testfile1
dir1
dir2
file1
hello.py
testfile
testfile1
pi@raspberrypi:~/work $
Firstly, ls command is sent to stdin, then processed by the shell and then the results are sent to stdout. > redirects the results to testfile1 instead of stdout.
>& redirects the results to testfile2 instead of stderr.
pi@raspberrypi:~/work $ ls wrongfile
ls: cannot access 'wrongfile': No such file or directory
pi@raspberrypi:~/work $ ls wrongfile >& testfile2
pi@raspberrypi:~/work $ cat testfile2
ls: cannot access 'wrongfile': No such file or directory
pi@raspberrypi:~/work $
Just like we use > for stdout redirection, we can use < for stdin redirection.
pi@raspberrypi:~/work $ cat < testfile1
dir1
dir2
file1
hello.py
testfile
testfile1
pi@raspberrypi:~/work $
Commands are files
In Linux "everything is a file". That includes the commands we are using. We can use which command to see where the command is located within the filesystem. With file we can find out more about what kind of file we are dealing with (in our case an executable file).
pi@raspberrypi:~/work $ which ls
/bin/ls
pi@raspberrypi:~/work $ ls -l /bin/ls
-rwxr-xr-x 1 root root 108804 Feb 22 2017 /bin/ls
pi@raspberrypi:~/work $ file /bin/ls
/bin/ls: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV),
dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for
GNU/Linux 3.2.0,
BuildID[sha1]=c24d547f9d1a35be487f168d83c3cbfcebeaa39c,
stripped
pi@raspberrypi:~/work $
grep, more, and less
The grep command allows you to search files for characters that match a certain pattern. Option n shows the line number of occurences (if any).
pi@raspberrypi:~/work $ grep -n import *
grep: dir1: Is a directory
grep: dir2: Is a directory
hello.py:1:from time import sleep
pi@raspberrypi:~/work $
less is a terminal pager program used to view (without changing) the contents of a text file one screen at a time. It is similar to more, but has the extended capability of allowing both forward and backward navigation through the file. Let's scroll through .bash_history (a rather large file) with more.
pi@raspberrypi:~/work $ pwd
/home/pi/work
pi@raspberrypi:~/work $ more ../.bash_history
ifconfig
pwd
ls -l
sudo apt-get update
sudo apt-get install netatalk
sudo vi /etc/dhcpcd.conf
sudo ifconfig wlan0 down
sudo ifconfig wlan0 up
ping 192.168.1.113
reboot
sudo reboot
sudo apt-get install tightvncserver
vncserver
ps aux| grep vncservr
--More--(1%)
pipes
Commands can be chained one after the other using pipes. A pipe (|
) connects the stdout of a command to the input of the following.
pi@raspberrypi:~ $ ls -al /etc | more