[kwlug-disc] KWLUG - The Kitchener Waterloo Linux User Group new content notification: 2010-08-31 01:05
webhost at kwlug.org
webhost at kwlug.org
Tue Aug 31 01:05:02 EDT 2010
Greetings mail-forum-merge,
------------------------------------------------------------------------------
Recent content - 2 new posts
------------------------------------------------------------------------------
1. Bash Command Line Quoting
Published Book page by john
[ http://kwlug.org/node/767 ]
If you've been following these articles or using the shell you know that
there are several characters that have special meaning in the shell. For
example you may have seen that the dollar sign $ is used to signify the
use of a variable. You may also have seen the asterisk * used to specify
a group of files, so-called file globbing. Even the space is a simple
special character, it separates a command and it's arguments. These are
only a few of the special characters, there are many more.
Special characters are interpreted by the shell before the arguments are
passed to the command. This relieves each of the commands from the
burden and allows the shell to provide consistency in the use of special
characters.
There are times that we find special characters in file names or we want
commands to see the special characters rather than have the shell
interpret or remove the special commands. Fortunately the shell provides
a way to do this, it's called quoting, and it uses three other special
characters.
Double quotes
Double quotes can be used to disable only some of the special
characters. It is useful in disabling all but the $, `, \ and !
characters. One basic way to look at this is that it tells the shell to
ignore shell globbing and spaces. e.g:
rm "file name"
Single quotes is the most powerful of quotes removing the special
meaning of all characters except the single quote. e.g.:
vi 'us$ account.txt'
Backslash can be used to quote a single character. We normally think
that quotes need to surround a string, but in the case of the backslash
since it quotes only a single character it is only needed before the
character. The backslash can quote any character as long as it is not
quoted by itself or a single quote. The only exception is the newline
character, in this case the newline is ignored and not passed to the
command. e.g.
cp us\$account.txt "us dollar account.txt"
Another method of quoting actually adds special characters. The $''
quote allows specification of many non-printable characters, like
newline, bell, tab and others.
echo $'bing \a'
For additional variables to use in the $'' quote view the man page for
bash (i.e. run man bash) and search for the QUOTING section.
Finally there is a $"" quoting method. This seems to be the same as the
double quotes, except that it will change how it works to suit other
languages.
Hyphens
Have you ever seen a filename that begins with a hyphen. These are often
mistakes, but if you find one it can be hard to get rid of. When you try
to use rm (e.g. rm -file the command will think that the -file are
options and will give an error message. This happens with all sorts of
other commands too.
The fix is easy and fairly consistent, use -- to separate options from
arguments. To use this method supply all your options before the
hyphened file then use -- and then the file name, e.g.
rm -r -- -file
Unprintable Characters
These can be another problem. Somehow, usually because of pressing a
function key at the wrong time, a file is created that begins or
contains a non-printable character. If the name only contains
unprintable characters or doesn't include anything unique that a file
glob can match then you have to resort to this trick.
First let's create a file that has the name of an escape character:
date > $'\033'
I used one of the quotes I mentioned above to create a file named with a
char 27, the ASCII code for Esc. In octal 27 is 33.
Now if you use ls you'll see a file with an odd name. Here is how to
identify it and delete it:
List the directory using the -b option, this will show non-printable
characters as backslash codes:
ls -lb
You'll see a file apparently called \033, this is your "Esc" file. To
delete it we'll use the same code:
rm $'033'
If the file only begins with that you can use a shell glob to handle the
rest:
rm $'\033'*
---
2. Bash Pattern Matching
Published Book page by john
[ http://kwlug.org/node/768 ]
Pattern matching in Bash is also called Globbing. It sounds all bloaty
and goey, but it's really boring and plain and not sticky at all, but
also quite useful. Glob is actually the name of the glibc function that
does the real work.
File pattern matching is usually about selecting groups of files, but it
can be useful in avoiding typing long file names. Rather than type out a
full file name, just type a pattern that contains a unique part and
you've matched the file.
How it Works
When you issue a command and the command or argument contains a pattern,
the shell first expands the pattern to one or more file names and then
runs the command. If the pattern matches the pattern is replaced with
the matching files and the command doesn't see the pattern, only the
matching files. If the pattern fails to match, then, as a default, the
command is given the pattern.
By default the shell doesn't match hidden file names, i.e. file and
directory names that begin with a dot (.) won't get matched. This
behaviour can be changed (see Configuring Pattern Matching below.)
Case Sensitive
By default file patterns are also case sensitive. Meaning that the files
"upper" and "UPPER" are different.
Asterisk
The most used pattern is the asterisk (*). It matches zero or more of
any character. It can be used at the beginning, middle or end of a
pattern.
Some examples are:
Pattern
Matches
*.pdf
Anything.pdf or just .pdf
img*jpg
img0001.jpg or imgjpg
index.*
index.html or index.php or index.html.bak
*
anything or really or Anything
Question Mark
A lesser used but still useful pattern is the question mark (?). This
indicates any one character.
Pattern
Matches
?ndex.html
Index.html or index.html
file.??
file.01 or file.js
More complicated
Rather than matching all characters you can specify a list of
characters, a range or a class of characters. Using the square brackets
([ and ]) you can specify the characters to match. Despite the pattern
taking up more than one character the pattern will only match one
character.
Pattern
Matches
messages.[123]
messages.1, messages.2 or messages.3
page[a-z].txt
pagea.txt, pageb.txt ... pagez.txt
page[-a-z].txt
As above, but also matches page-.txt
page[^m-z].txt or page[!m-z].txt
Doesn't match files pagem.txt through pagez.txt but matches all others
(i.e. page?.txt)
Classes can be used, these are shortforms for full ranges of characters.
The following clases can be used: alnum, alpha, ascii, blank, cntrl,
digit, graph, lower, print, punct, space, upper, word, xdigit. Use a
class like this:
ls img[:digit:].jpg
That matches img0.jpg through img9.jpg. It seems like it's useless, but
consider that this works independant of language. The real use of these
classes is that if the locale changes (i.e. the language) then the
characters that match also change. So this will match English or Arabic
numerals.
Extended Patterns
Extended patterns can be handy in niche situations, but you'll probably
find that they are disabled by default in your bash. To enable them you
would have to run:
shopt -s extglob
And like all the settings I've mentioned, if you want it to be turned on
every time to start a shell you need to add it to your .bashrc file or
the system-wide /etc/bashrc file.
With extended patterns you can create more complex patterns that match
more than a single character but less than all characters of any length.
?(pattern-list)
Matches zero or one occurrence of the given patterns
*(pattern-list)
Matches zero or more occurrences of the given patterns
+(pattern-list)
Matches one or more occurrences of the given patterns
@(pattern-list)
Matches one of the given patterns
!(pattern-list)
Matches anything except one of the given patterns
The patters can be any of the regular patterns so +([:digit:]) matches
one or more digits.
Configuring Pattern Matching
There are shell options that allow control over how the shell matches
patterns and how it reacts to failed patterns.
dotglob
If set, bash includes filenames beginning with a ‘.’ in the results
of pathname expansion.
extglob
If set, the extended pattern matching features described above under
Pathname Expansion are enabled.
failglob
f set, patterns which fail to match filenames during pathname
expansion result in an expansion error.
globstar
If set, the pattern ** used in a filename expansion context will match a
files and zero or more directories and subdirectories. If the pattern is
followed by a /, only directories and subdirectories match.
To see if these options are set run:
shopt dotglob
To set it:
shopt -s dotglob
To unset it:
shopt -u dotglob
As you have come to expect it, to make these changes permanent you need
to add the shopt commands to your .bashrcfile or the system-wide
/etc/bashrc file.
Seeing File Expansion Work
The easy way to see file expansion working is to use the echo command.
Just give it a pattern and it will print the results.
echo *.jpg
Another way it to position you cursor at the end of the pattern and
press Tab twice and the shell will list matching files below. You can
also expand the pattern on the line by positioning your cursor at the
end of the pattern and pressing Ctrl-x then *, the matching files now
appear on the command line.
--
This is an automatic e-mail from KWLUG - The Kitchener Waterloo Linux
User Group.
To stop receiving these e-mails, change your notification preferences at
http://kwlug.org/user/28/notify
More information about the kwlug-disc
mailing list