Difference between revisions of "CSC231 Bash Tutorial 4"

From dftwiki3
Jump to: navigation, search
Line 146: Line 146:
 
   
 
   
 
:You have captured the '''stderr''' output to a file.
 
:You have captured the '''stderr''' output to a file.
 +
<br />
 +
=Getting Rid of Stderr=
 +
<br />
 +
Sometimes we know that there will be message sent to '''stderr''' by the command/program, but we don't want to see them.  Possibly because there are too many.
  
 
+
For example, assume we want to apply '''du''' to all the student accounts, which live in /Users/classes/ and sort the resulting list to see who's hogging up the most disk space:
 
+
 
 +
du /Users/classes  | sort -n | tail -n 10
 +
 +
* Try the previous command.  See how the error messages are polluting the output?
 +
* What we could do, instead, is sent the '''stderr''' lines to a file, and sort only the '''stdout''' lines coming out of '''du''':
 +
 +
du /Users/classes 2> duErrors.txt  | sort -n | tail -n 10
 +
 +
* Try it.
 +
* The output is much cleaner, isn't it?
 +
*
 
</showafterdate>
 
</showafterdate>
 
<br />
 
<br />

Revision as of 16:59, 22 February 2017

--D. Thiebaut (talk) 14:13, 22 February 2017 (EST)


<showafterdate after="20170224 13:00" before="20170601 00:00">

Using the Vi Editor

Redirection


  • We have seen in the previous lab how to use pipes to take the output of a program and feed it to the input of another.
  • Redirection is similar, except that the input or the output is fed from, or fed to a file, respectively.


Example 1: storing the output of a command into a file


  • Try this:
last

this will list the last login times of all the users on Aurora. If you want to target a particular user, say 231b, you can try this:
last | grep "231b "               (make sure there's a space after the b)
  • Assume you want to store these login time into a file, so that you can share it with somebody else, or send as an attachment. You simply use the > sign to store the output of the last command into a file:
last | grep "231b "  >  logins231b.txt

  • You won't see any output, as it is being redirected. Look at the files in your directory and see that you have a new file called logins231b.txt.
  • Display the contents of this file with the cat or with the less command.


You now have a new way of storing the output of a program into a file.


Challenge #1:

QuestionMark1.jpg


Create a text file called "231Students.txt" that contains their last login information, but make sure the information from User 231b (your instructor) is not stored in the file.





Side-step: Sorting text


Linux sports a command to sort text. It's called "sort." To see how it works, try this:

last | sort

  • If you had wanted the output in reverse order, you could have typed:
last | sort -r

  • Sometimes the information returned by a linux command contains numbers at the beginning of the first line. du, which returns the "disk usage" of a directory, i.e. the amount of disk space taken by each file, is such a command. Let's try it:
du /etc

You get a list of all the files in the /etc directory, with their size at the beginning of each line.
  • Try to sort this list:
du /etc  | sort

  • See the problem? Sorting numbers alphabetically does not yield what we expect. Instead we can tell sort to sort numerically:
du /etc  | sort -n


Challenge #2:

QuestionMark2.jpg


Create a text file called "231Students.txt" using redirection, and make it contain the login information for 231 students, sorted in alphabetical order, but make sure the information from User 231b (your instructor) is not stored in the file.







Challenge #3:

QuestionMark3.jpg


Create a text file using redirection that contains only the 10 largest files found in the /etc/ directory. The file should be called top10etcFiles.txt. Be careful that the last line of the output of sort is the total of all the files, and shouldn't be included in the top10etcFiles.txt file.







Redirecting Stderr


  • Run the du command another time, and pay attention to the lines that contain a "Permission denied" message:
 du /etc

When I run it, I get these messages interspersed here and there:
28	/etc/pm
4	/etc/ndiswrapper
8	/etc/rc4.d
4	/etc/mate-settings-daemon/xrandr
8	/etc/mate-settings-daemon
du: cannot read directory ‘/etc/chatscripts’: Permission denied
4	/etc/chatscripts
28088	/etc

These messages are error messages reported by du. They do not create du to crash. du is just reporting failure to look at a particular directory or file.
  • Let's capture all these "Permission denied" message to a file:
du /etc  > duErrors.txt

  • and let's look in the file just captured:
cat duErrors.txt

?
  • Do you see anything in duErrors.txt?
  • Why?
  • What's happening?
The explanation is that when du outputs one of the "Permission denied" lines, it does not output them to sdtout, the standard output. It outputs the to a different output stream, called stderr, for standard error. This is the stream one should use to output error messages.


By default, outputs to stderr and stdout are sent to the screen. If you use > to capture the output of a program, you capture only the part sent to stdout and not the part sent to stderr. To capture the output sent to stderr to a file, we need to use 2> as a symbol:
du /etc 2>  duErrors.txt
and now try:
cat duErrors.txt

You have captured the stderr output to a file.


Getting Rid of Stderr


Sometimes we know that there will be message sent to stderr by the command/program, but we don't want to see them. Possibly because there are too many.

For example, assume we want to apply du to all the student accounts, which live in /Users/classes/ and sort the resulting list to see who's hogging up the most disk space:

du /Users/classes  | sort -n | tail -n 10

  • Try the previous command. See how the error messages are polluting the output?
  • What we could do, instead, is sent the stderr lines to a file, and sort only the stdout lines coming out of du:
du /Users/classes 2> duErrors.txt  | sort -n | tail -n 10

  • Try it.
  • The output is much cleaner, isn't it?

</showafterdate>






<showafterdate after="2017024 11:30" before="20170601 00:00">

Challenges Solutions


Challenge 1
last | grep "231b" | grep -v "231b "  > 231students.txt

Challenge 2
last | grep "231b" | grep -v "231b " | sort > 231students.txt
Challenge 3
du /etc | sort -n | tail -n 11 | head -n 10 > top10filesInEtc.txt

</showafterdate>