# 3.1 Find, Grep and IO ### Input Output and Error Redirection is a feature in Linux such that when executing a command, you can change the standard input/output devices. The basic workflow of any Linux command is that it takes an input and gives an output. The standard input (stdin) device is the keyboard. The standard output (stdout) device is the screen. These are called **streams**. We can control these with **redirects** and **pipes**. Here are all the streams available: |Streams |Usage |stream number| |:-------|:--------------------------------------------------------------------|:-:| |stdin |The keyboard or whatever you type into the terminal | 0 | |stdout |This is the result of a command | 1 | |stderr |If the command or bash makes any error this is put on the error steam| 2 | Here are some redirects and pipes: |Redirects and pipes |Explanation | |:---------:|:-------------------------------------------------------------------------------| | \| |Pipe this takes the stdout of a command to make it the stdin of the next command| | > |Redirect stdout to a file and replace file | | >> |Redirect stdout and add it to bottom of file | So you can send input outputs between commands. Let's examine the following command: ```bash cat textfile | grep word > newtextfile ``` Let's deconstruct the command: |command|stdin |pipe|command|stdin|redirect|stdin | |:-----:|:------:|:------:|:-----:|:---:|:---:|:------------:| |cat |textfile| \| |grep |word |> |newtextfile| Let's do some practice with this. ### Grep **become root** We are going to use grep to get data from a file. You will find a book at ```/media/onthegenealogyofmorality```. We can read the book with the ```cat``` command; this command will paste the content of any text file to stdout, aka the terminal screen. ```bash cat /media/onthegenealogyofmorality ``` We want to know how many chapters there are in this book….. ```bash cat /media/onthegenealogyofmorality | grep chapter ``` Results should look like this: ```bash [root@rhcsa media]# cat onthegenealogyofmorality |grep chapter chapter 1 chapter 2 chapter 3 chapter 4 ``` Let's make a directory to make the text file in: ```bash mkdir –p /root/found/ ``` Now we wish to send these results to a file to be stored and checked later. Note: this is one line. ```bash cat onthegenealogyofmorality | grep chapter > /root/found/chapterlist.txt ``` Results inside the file can again be read with cat (or vim). The result of that should look like this: ```bash [root@rhcsa media]# cat /root/found/chapterlist.txt chapter 1 chapter 2 chapter 3 chapter 4 ``` ### Find On your vm, become root and use the following command to find files: ```bash find ``` We can use find to search from any starting folder on any paramater that identifies the file. For example: we can use "find" here to locate all files from the user ```nietzche``` and since we start the search from the ```/``` root of the filesystem: ```bash find / -user nietzche ``` The result should look something like this: ```bash [root@rhcsa ~]# find / -user nietzche find: ‘/proc/1793/task/1793/fd/5’: No such file or directory find: ‘/proc/1793/task/1793/fdinfo/5’: No such file or directory find: ‘/proc/1793/fd/6’: No such file or directory find: ‘/proc/1793/fdinfo/6’: No such file or directory /var/spool/mail/nietzche /var/secret/file2 /home/nietzche /home/nietzche/file1 /media/onthegenealogyofmorality /srv/file3 /shared/file4 ``` Now that we found the files, we want to copy them to a found directory, so first we need to make the directory. ```bash mkdir –p /root/found ``` Now let's find and copy the result. It is one line! We use xargs for this: ```bash find / -user nietzche | grep file* | xargs cp -t /root/found/ ``` The result should look something like this: ```bash [root@rhcsa found]# ll total 0 -rwx------. 1 root root 0 Nov 29 16:10 file1 -rwx------. 1 root root 0 Nov 29 16:10 file2 -rwx------. 1 root root 0 Nov 29 16:10 file3 -rwx------. 1 root root 0 Nov 29 16:10 file4 ```