DæmonNews: News and views for the BSD community

August 2000 Get BSD New to BSD? Search BSD Submit News FAQ Contact Us Join Us
Search


Get BSD Stuff

Help, I've Fallen

by Gary Kline, David Leonard and Dirk Myers

Perl! Text Editors! Df! Shells! And more... Thrills and chills as the Answermen show you around a land that isn't Kansas any more.




Q1: Why does perl show these errors? How can I stop them?




 $ perl -e 'print "hello!\n"'
 perl: warning: Setting locale failed.
 perl: warning: Please check that your locale settings:
         LC_ALL = (unset),
         LC_CTYPE = "en_US",
         LANG = (unset)
     are supported and installed on your system.
 perl: warning: Falling back to the standard locale ("C").
 hello!
 $

These errors are generated because perl is trying to set up for a locale setting of 'en_US', and failing. The locale environment variables are used to tell the system how it should behave when doing things which are common, but which vary in different parts of the world -- for example, formatting a date. Perl attempts to determine the locale it should use by looking at the environment when it starts up. Perl will complain when any of the environment variables used to indicate your locale are set to values which don't exactly match the locale information stored on your system. The solution is to set these environment variables to the precise values perl expects to see.

Assuming that you intended for the locale to be English, in the United States variant, add the following lines to your initialization file (.login, .profile, .bashrc, .zlogin). (The lines shown are for csh, and the E.)

setenv LC_ALL   en_US.ISO_8859-1
setenv LC_CTYPE en_US.ISO_8859-1
setenv LANG en_US.ISO_8859-1
setenv LESSCHARSET latin1

For more information on perl's locale support, see the perllocale documentation included with the perl distribution. You can read this by typing 'man perllocale' at the shell prompt.




Q2: How do I change the default text editor?


Most programs intended to be invoked from the command line use the contents of the EDITOR environment variable as the program to be invoked when a text editor is needed. To change the default text editor, then, you just need to set the EDITOR environment variable in your home shell startup file. For example, to set the editor to emacs, with a Bourne-like shell:

$ EDITOR=emacs ; export EDITOR

and for the csh-like shells:


% setenv EDITOR emacs

(Of course, this will only work if emacs is installed on your system, the executable is named 'emacs', and the executable is in your PATH.)


Q3: What's the correct way to set environment variables?

Sometimes you'll see VARIABLE assignments as
   export VARIABLE=value
and at other times,
   VARIABLE=value
   export VARIABLE 

Which is the "correct" way?

If you want to make your shell set-up files anywhere near portable, it is probably better to use


   VARIABLE=value
   export VARIABLE 

The reason is simple. The basic syntax used here is derived from the original Bourne shell. Although it's shorter, the following:

  export VARNAME=value 

did not work in the original Bourne shell, so it is not guaranteed to work in all Bourne-type shells.

If you are writing a shell script to be widely used (say for teaching or illustrative purposed), it makes sense to use the slightly longer syntax that is sure to work in all Bourne or Bourne-like shells.

On the other hand, if you don't care about portability and are certain that your script will only be used on bash, ksh, zsh, then, sure, use the shorter notation.

There's another variant on this question, of course: csh, and shells derived from it, use a completely different syntax:

% setenv VARNAME value

To make your life even simpler if you're cutting-and-pasting the setenv/unsetenv syntax of the csh, putting the following functions in the initialization files for a Bourne-like shell will let the csh syntax work for you there, too.


setenv() { export "$1=$2"; }
unsetenv() { unset "$1"; export "$1"; }




Q4: I'm writing a C program, and I want to make sure it's portable to the BSD family. I think I've got a handle on the actual code I need to include, but I'm not sure how to make sure it's included. Is there a common way among FreeBSD, NetBSD, and OpenBSD to #define BSD ?


The C preprocessor symbol `BSD' is defined in <sys/param.h>.

Without the C compiler (usually gcc) should only automatically define preprocessor symbols such as `__unix__' and `__GNUC__'. Non-ANSI C compilers will often define the symbol `unix'. For some operating systems, the compiler is also configured to predefine an operating system specific symbol (such as `__FreeBSD__'.) If you are really interested, you can find out what symbols are automatically defined with this command:

gcc -x c /dev/null -E -dM

Knowing that sys/param.h will #define BSD on a BSD system, you can do something like this:
#if defined(__unix__) || defined(unix)
#  include 
#endif

#if defined(BSD)
/* BSD-specific things */
#endif

Beware, though. If you intend to write portable code (and we encourage you to do so!), it's easy to wind up writing things like:

46:#ifdef        __linux__
65:# if (BSD >= 199103) || defined(__linux) || defined(ultrix) ||
defined(AIX) ||\
79:#if !defined(BSD) && !defined(__linux) && !defined(UNICOS)
#if (defined(BSD)) && (BSD >= 199103) || defined(__linux) ||
defined(AIX)
When things get to this point, your time may be better spent learning to use GNU's autoconf.


Q5: Someone said that the df utility was especially useful? Can you explain how? I thought that df only tells how much diskspace is free.

df does indeed report on the free space of mounted disks. It also reports on some other statistics of disk usage which you may or may not be interested in.

`df -i' will show you how many inodes remain on the filesystem. Inodes are basically file slots and a fixed number of them are allocated when the filesystem is first created. If you run out of inodes, you can't make any new files - even if you have free disk space! Some network news servers have been known to create huge numbers of tiny files and run out of inodes.

`df -n' is handy if you are having problems with filesystems - especially remote filesystems or experimental ones - that cause your processes to `lock up' whenever they access a disk. df without the -n flag may lock up in those cases too. When you include -n, df will show you whatever the most recently obtained statistics were, rather than ask a possibly dead filesystem for them.

The '-k' flag directs df to report numbers in kilobytes which some people find more useful than the default unit of `disk blocks' (usually half a kilobyte).




Q6: How can I mount a msdos floppy drive as me, not root?

You may know that the general way to mount a DOS floppy (as root) is with:


 # mount -t msdos /dev/fd0 /

But that command only works if you're root. Before telling you how to work around this, it's important to understand why this is the default. The answer, as you might suspect, boils down to security -- if you let arbitrary users mount file systems, the security on your machine is more easily compromised. There's also the potential for inadvertent problems, as BSD tends to panic when mounted filesystems suddenly disappear (for example, if the floppy is removed from the drive before the filesystem is unmounted), or if the filesystem is corrupted in certain ways.

Now that you understand some of the whys and wherefores about not letting anyone but root mount a floppy, here's how to let any user do it:

In other words,


    # chmod 0666 /dev/fd0
    # sysctl -w vfs.usermount=1
 
[Note: NetBSD does not have this sysctl item. User mounting of floppies is always available on NetBSD.]

Then as yourself, create a mountpoint in your home directory. If you are usr `smith' and you want to call your mountpoint `floppy' type


    % mkdir /home/smith/floppy 

and you will be able to mount a floppy (and in this example, as msdos floppy) with the following command:

    % mount -t msdos /dev/fd0 /home/smith/floppy

If you run xdm on your console, then in /usr/X11R6/lib/X11/xdm there are usually scripts called GiveConsole and TakeConsole. They typically change ownership of /dev/console to the user logging in on ":0". It is trivial to extend these scripts to chown/chmod 0600 the local floppy devices as well. If you have come from a Macintosh background, you could even insert the right commands to umount and eject the floppy!

As usual, there's a lot more information on how to use the mount command in the man page for mount. We've only scratched the surface of the options available.

Q7: Can you help me with some of the tape drive utilities? I tried using mt and got error output that I didn't understand at all. Some concrete examples of the use of
 tar -, and mt, sa

would help!

We discussed uses of tar months back during a discussing of making backups.... Here are a few examples of using tar on your tape device. For purposes of this Q/A, let's assume that your tape device is /dev/rsa0.0.

For this discussion of tar, we'll use the following flags:
create Creates a tar archive
file Tells tar which file (or device) to use.
extract Retrieves files from a tar archive
table of contents Use the table of contents in the archive.
verbose Tells tar to report information on every file it archives or retrieves
zip Use gzip compression

Now, let's look at these flags in action. To backup your /home directory using tar, the following ought to work:

% tar -cvf /dev/rsa0.0 /home
To extract the data from your tape:
% tar -xvf /dev/rsa0.0
To back up your entire system with gzip compression:
% tar -czvf /dev/rsa0.0 /
And to restore everything from an archive created with gzip compression:
% tar -xzvf /dev/rsa0.0

% tar -zt "*FWF*"

will provide a table of the entries with ``FWF'' in their filenames, and

% tar -xt "*FWF*"

will extract files with "FWF" in their file name, if any are in the archive.

The mt utility has enough options to keep you busy for years! Here are a few simple examples:

% mt rewind
rewinds the tape in your default tape drive or
% mt -f /dev/rsa0.0 rewind
which uses -f to select any other drive.

Other uses of mt

% mt -f /dev/rsa0.0 erase
will erase the tape in /dev/rsa0.0 ( surprise), and
% mt -f /dev/rsa0.0 retension
will re-tension the tape by one full rewind back and forth.

The sa utility that you asked about is for printing system accounting statistics and has nothing to do with tape device.



About the Authors

Gary Kline has been porting code since the late 1970's. When he isn't hacking code, he's hacking prose or quasi-poetry, or listening to jazz radio and slurping down espresso.

For going on four years he has been writing the software equivalent of a mind-machine, dubbed Muuz, and has already released some alpha code for FreeBSD. Check the FreeBSD ports tree if you are interested.

http://muuz.deadbbs.com will have the documentation and source under CVS.

[home| mail]

David Leonard is a PhD student in the Department of Computer Science and Electrical Engineering at the University of Queensland, Brisbane, Australia.

His area of research is QoS-adaptive component software architectures, and in his spare time is a developer for the OpenBSD project. That said, David enjoys living the quiet life with his wife, Kylie and cat, Mu. He especially enjoys frequenting Moreton Bay's many fabulous places to eat. Mmmmm!

[home| mail]

Dirk Myers works for a company that builds bar code scanners, making Unix systems at the company do things which are useful for document control. Much of his spare time is spent losing at Go, enjoying the central Oregon outdoors, and making Unix systems do things which are not useful for document control. He is married to Shanie, a scientist, and spends the rest of his spare time trying to understand the things his wife does with her time. Together, Dirk and his wife own large quantities of domestic animals, and they have recently acquired a house to put the animals in. Dirk is still looking for the man pages for the house.

[mail]




Author maintains all copyrights on this article.
Images and layout Copyright © 1998-2004 Dæmon News. All Rights Reserved.