You may want to write over an existing file. Or you may want to append to a file, but don't know if the file exists or not. If you want to disable this feature, type unset noclobber You may wish to keep this feature enabled, but disable it on a line-by-line basis. Just add a "! This is like saying "I really mean it! That is, when you want to append to a file that doesn't exist, or write to a file that may exist. A complete list of all of the variations, and their meaning, is below.
These options warned the user if a file was going to be destroyed. The C shell supported an alias feature that allows you to define new commands. If you type alias move mv then when you execute the command "move," the C shell performs a substitution, and executes the "mv" command.
The new options, along with the alias command, allowed new users to specify alias mv mv -i alias cp cp -i alias rm rm -i and before any file is destroyed, the system would warn you. C Shell Start-up Files Since I've started talking about the C shell interactive features, it's time to discuss the start-up files, or files whose name starts with a dot.
The shell executes the source command on the file. If a C shell script starts with! Think of the -f flag as the fast option. I recommend that every C shell script start with the "! Remember - this is the user's personal file. My file is different from yours. If I executed that script, it might not work the same as when you execute the script.
A shell script that depends on the contents of the. It is important to understand when these files are sourced. When you execute a program like cmdtool , shelltool or xterm , The value of the SHELL environment variable is used, and that shell is executed. If the shell is the C shell, then the. If this is the C shell, then. It is executed when the user logs onto a system. These sessions are called a login shell. Assuming you have specified the C shell as your default shell, typing your username to the "login:" prompt on a console, or using the telnet or rlogin command, then this is a login shell, and the.
Ever wonder how the shell knows this? The mechanism is simple, but most people don't know about it. When the login program executes a login shell, it tells the program that the first character of the program is a hyphen.
That is, if you execute "-csh" instead of "csh. If you execute "csh. If you execute "-csh," both the. A shell created in this fashion executes the. Without the hyphen, just the. This only happens when the shell is a login shell. What goes where?
Knowing when each file is used is very important if you want to keep your account as efficient as possible. People have a tendency to add commands to any file, or in some cases both files. Finally the system behaves the way the user wants, and the changes are kept where they are without understanding the whys and wherefores. As always, I believe it providing tables, allowing you to look up the exact behavior in each condition.
Let me list them. Determining which commands are the ones you want to execute. You discover a useful setting, and want to add this feature to all sessions. Learning when you want to execute these commands. Does this feature need to be set once, or for every shell? Executing commands at the wrong time. Some people put "biff y" in their. This is wrong. It should be in the. Learning when the two files are sourced, and in which order. Some people think the.
This seems logical, because the. Don't add commands without thinking of where they go. Placing commands and options in the wrong place, may be meaningless, and slow down your shell. All of these problems confound the new C shell user. So how can you distinguish between these different cases? Well, the C shell sets various variables under different conditions. The operating system also has variables, independent of the shell. I'll briefly describe the difference, and provide a template. Why is this important?
I have a large number of aliases. How large? I currently have about aliases. You may or may not think this is large. It is significant, however. I noticed by shell was taking longer and longer to execute scripts. However, I found there are two problems with this.
Good coding style says we should keep modules short and easy to understand. The other problem was a matter of efficiency. Even though the shell didn't have to execute the lines of aliases, it still had to read each line, looking for the "endif" command. This slowed down the shell. Therefore I currently use something like this: if! The current terminal A second important condition used to customize your shell session is the current terminal.
This is learned by executing the program "tty. I often see something like the following in a. This is good practice, because if the command ever fails, the variable will have an empty string as a value. The double quotes prevent this from becoming a syntax error.
Local variables vs. Environment variables There are two kinds of C shell variables: local and environmental. Local variables are local to the current shell. If a new shell is created, then it does not have these variables set. You have to set them for each shell. Environment variables are exported to all sub-shells. That is, if you set an environment variable, and then create a new shell, the new shell inherits the value of this variable.
Inherit is the essential concept. The child can inherit the traits of the parent, but anything the child does to itself does not affect the parent.
If you specify an environment variable before you start up the window system, then all new shells, i. But if you set an environment variable to a different value in each window, this has no effect on the parent process, which is your login shell. You can set environment variables in your.
However, this is unnecessary, because any variable set in the. There are two reasons you need to set an environment variable in the.
The first is because you need to customize it for each shell. Perhaps different windows have different values. The second reason is that you need to look up something, by executing a program, and want to optimize your shell, so that this only has to be done once. Suppose you wanted to learn what your current computer is called.
If you want to optimize your shell, then only do this once. The logical place is to do this in your. But you may want to use this information for something that is set in your.
One way to solve this problem is to check for a special environment variable, and if it is not set, then execute the command, and set the variable. An example is: if! Many people perform different actions based on the current terminal type. If you log onto a system with a device local to the system, the terminal type is known. If you use rlogin or rsh to create an interactive session, the terminal type is communicated to the remote system.
If you use the telnet command, the terminal type is unknown, and must be determined somehow. Once the terminal type is known, the user often customizes the keyboard configuration. In particular, some characters, especially the delete key, differs on different terminals. One terminal may have an easily accessible backspace key, and another has a convenient delete key.
The command to modify this is the "stty" command. All scripts that start with! Following the principle of modularity, most of the UNIX commands are separate programs. Only a few are built into the shell. These external programs may be scattered in dozens of directories. When you ask for a command that the shell doesn't understand, it searches the directories in the order specified by the search-path, and executes the first command it finds with the name you specified.
And trust me on this, systems that do not behave consistently are bad for your mental health. I knew a programmer who was writing software for a system that behaved unpredictably. He receives excellent care nowadays, but he always asks me the same question. The world will never be safe for programmers until we eliminate all non-deterministic systems. The curly brace is necessary in this case, because the C shell has the ability to perform basename -like actions if a color follows a variable name.
The curly braces turn this feature off. Without the braces, you would get a syntax error. The braces could be added in the Bourne shell example above, but it isn't required. The C shell has an alternate way to modify the searchpath, using a list. The Bourne shell uses a colon as a separator, and a blank value is used to indicate the current directory. Since any number of spaces can be used as a separator, something else must be used to indicate the current directory.
The period is used instead. This is logical, because ". This is a security problem. See the sidebar to fully understand the danger of this action.
It might seem confusing that there are two path variables, one in upper case, and the other in lower case. These are not two different variables. Just two different ways to set the same variable. Change one, and the other changes. Because the C shell uses a list, this allows some convenient mechanisms to examine and manipulate the searchpath. Suppose you want to write a simple version of the "which" command. The C shell makes this an easy job:! Surprisingly, my measurements show the Bourne shell version is faster.
Well, I found it surprising. I expected the C shell version to be faster, because it doesn't use any external programs.
The Bourne shell version executes three additional processes because of the back quotes. Therefore four programs compete with one C shell script.
And the C shell still loses. Does this tell you something? The system comes with a C shell script called "which. This is fine, but I prefer the above script, because it tells me about all of the commands, and runs much faster. I called it "Which," with a capital "W," so I can use either one. The Korn shell has a build-in command, called "whence. But this really isn't necessary. Like all environment variables, all newly created shells get their environment from their parent.
Some people therefore specify it in their "login" file. All new shells will have this searchpath. I set my searchpath before I start my window system.
This is very flexible, and quite easy to do. Just create a shell script that specifies your new searchpath, and then start up the windowing system. If you use OpenWindows, an example might be if! If you then create a new window using a command like shelltool , or xterm , that window will inherit the searchpath from their parent. I specify my searchpath in a file called ". Any time I want to, I can define or undefine variables, and source the same file to reset my path.
This allows me to use different windowing systems, or different versions, and have one main file to control my search-path. Another way I change my searchpath is with an alias.
You may want to define the following aliases: alias. You can make aliases as simple or as complicated as needed. Undoing any changes One of the simplest way to reset your path is to type the new path on the command line.
If you have problems, you can always change your ". After this, all new shell windows you create will have the new path. Another convenient way to undo the change is to execute another shell. That is, before you experiment, type csh Then modify your searchpath. When done, type a Control-D.
This forces the current shell to terminate, and the environment variables of the earlier shell are restored. Summary I've discussed several ways to change your searchpath. As a summary, here are the methods: Explicitly set the path.
Specify it in your. Specify it in another file, and source this file. Execute a shell script that changes the path, and then executes another program or shell. Use an aliases to do any or all of the above. No one method is right for everyone. But don't think you have to set your searchpath in your ".
Other solutions are possible. In fact, next month, I will discuss how to optimize your searchpath. Sidebar Some people put their current directory in their searchpath. If you ever change directories to one owned by someone else, you may be tricked to execute their commands instead of the ones you expect. Don't believe me? You've forced my hand. This is a little better, but you can still fall victim to the same trap.
Have you ever made a typo when you executed a command? I could call the script "mroe" or something similar, and still delete all of your files.
Now - are you willing to risk this? I hope not. I tell people how dangerous this is. Remember, other actions could be taken instead. Personally, I don't have the current directory in my searchpath. It was painful at first, but I soon learned how to adjust. When I want to execute a command in the current directory, I just type. I sleep much better at night. This month, I will discuss ways to optimize your path. What do I mean by optimization? Well, to tell the truth, I have looked at a lot of C shell start-up files, and I shudder at what I see.
Some people have dozens of directories in their searchpath. I also see people walking around with a gloomy look, as if a storm cloud is circling over their head.
I can't get any work done. A server went down, and it didn't bother me at all because it wasn't in my searchpath. When some people discover a directory that contains useful programs, they add it to their searchpath. The searchpath grows and grows, until it becomes so convoluted, no one understands it. That's the wrong thing to do. You see, I created a special directory that contained symbolic links to files on remote systems. Because the directory is on my local workstation, I am not affected if a server goes down.
The only time I have a problem is if I use one of those executables. That process will freeze, but only that process. All I have to do is create a new window, and continue working. I call this a cache dirctory, and I know that isn't the best name for it.
A better name ought to be "favored. I will admit that solving this problem isn't trivial. In fact, I wrote a program to help me figure out what to do. Several programs, as it turns out. Let me describe them. Programs to Optimize the Searchpath The first script, and the most important one creates and maintains the cache directory. The script CreateCacheDir follows:! Actually, not a cache, but a link. Usage CreateCacheDir Cachedir dir1 [dir I wrote some programs to measure how good or bad my searchpath is.
You might find them useful. Programs to measure your efficiency One way to simplify the searchpath is to identify directories that are really symbolic links to other directories.
This script, called ResolveDir , will identify these cases:! If the file is on the local system, it returns the host name.
Since I am talking about the C shell, I started to write the script in this shell. However, because of limitations of the C shell, I have to split one script into three files.
The main script, AnalyzePaths , calls two scripts:! Each line contains the directory name, the final name if a symbolic link and the system that provides the directory:! For instance, it reports directories that don't exist, redundant directories, and specifies remote directories that can be eliminated. Using these scripts will give you a set of tools to improve your searchpath. Do it right, and may you never have your workstation freeze again.
Specifying system-specific searchpaths So far, I've explained how to optimize your searchpath. But that is only part of the problem.
If you only used one computer, simplifying your searchpath would be easy. But logging onto many different computers makes life "interesting," as the ancient Chinese curse goes. You could do what most people do, and keep adding directories ad nauseum until every possible directory is in your searchpath.
Of course, as I explained last month, this makes your account as stable as a one-legged elephant. I have a solution, based on specific rules. Here is the short list: Understand directory characteristics. Consider a local home directory Let me describe each of these rules. Understand directories characteristics. The UNIX file system was designed to be the single common structure to perform all operations.
All input and output, all devices, and the internals of the operating system are reachable by using special files. With NFS, this was extended to include remote files, making them look like local files, and making all file-based UNIX utilities capable to operating on remote files. However, all directories don't have the same characteristics. The directory is read-only, and identical on other systems of the same architecture.
Typically writable by super-users only. Writable by various processes, programs, and users. Often not backed up. Not visible by other systems.
Log onto other systems, and see the same files. This may be private to the system. Make sure you understand how the files at your site are organized. Most new workstations have lots of disk space, and it is rare that the systems don't make it available. Users should know if the files are visible to other systems, and if the files are backed up or not.
Some directories are project-related. Executables are only used when working on the project. These are what I call "optional" directories. If they are missing, you can still do other work. Other directories are mandatory. Some companies do not have a consistent naming strategy. This is a serious problem. If the location of a single file changes when different machines are used, then the user has to deal with this extra complexity, which is very difficult, and if not taken care of, can lead to irritability, moroseness, and eventually--insanity.
Sun's automounter can help. For instance, you can set up a network so that your home directory always has the same name, even if it is moved to another system.
Another popular and practical convention is to specify machine-specific files using a path that contains the name of the machine. You may want to write up your strategy. This helps clarify some of the decisions. Backed up.
Not shared. But deciding on a naming strategy is the first step. It doesn't matter what the convention is, as long as it is consistent. But if it's too complicated, errors can occur. When possible, keep things simple. Remove non-essential directories. If you don't need to use certain executables all the time, then add them when you need them using an alias.
To repeat the lesson from two months ago, don't set the path in your ". Inherit it from your environment. When you want to add a directory, change your environment for that window. Once you have removed all of the directories you use occasionally, you still might have several directories that are on other systems.
What then? The solution is simple. Create a directory on your local system, that contains symbolic links to the real files. Then remove the original directory from your searchpath, and add the new one. I discussed this in detail last month. But there is one more step. Consider a local home directory Most large installations share user home directories.
No matter which system you log onto, you are in the same spot. This is convention, but there are two problems. The first concerns efficiency, and the second security.
The efficiency is a concern if the server providing this file goes down. The security is a concern, because anyone who can gain superuser access on any system that mounts that home directory, can break into that account if you use rlogin, and have access to your files. To solve both problems, create a directory on the local system that has copies of some of the critical files, like ". A better solution is to eliminate the "rlogin" and "rsh" services, using a program like "ssh" instead. But that's another topic.
Having a home directory local to your main computer can increase your efficience, by removing the dependance on other systems. You can have your own directory for executables, for instance. Customizing your environment I'll go through it a step at a time.
Remember, I do not recommend you always set your searchpath in your ". Set it when you need it, like starting up a window system. Assume the searchpath is controlled by a file called ". Otherwise a default searchpath is specified. The file ". This file can be quite simple. For instance, if the file ". No other programs will be executed. The system doesn't even need the "uname" executable. Here is another example, names "path. Still, this doesn't solve all cases. In particular, SunOS 4.
X and 5. X systems have different searchpaths. Here is a file that shows one way to automatically change the searchpath based on the version of the operating system:. SunOS copied from. Other approaches also make sense. The second one could contain all Sun specific shell scripts. The third one could contain all executables for a Solaris 5. And the fourth directory can contain machine-dependent executables. It is a bit complex, but it offers a lot of flexiability.
I hope you find it useful. These included band printers, 9 track tape drives, oddly 9-track was before 8-track , and disk platters.
The most fearsome of all the beasts was the TeleType, able to cause piercing headaches. Quieter machines evolved, like the Silent , and the DecWriter. A new beast was seen wandering the dark and desolate laboratories.
It was quick. It was silent. A common sound was the stampede of fingertips, as the Hacker stalked his or her prey - the perfect program. Faster, faster went the fingers, but it was never fast enough. That perfect program was just around the corner, but rarely was it caught. One hacker, in an effort to go faster still, decided to enhance his shell in such a way that all he had to do was take a tiny step in a direction, and the shell knew what he wanted to do.
That hacker added history. And thus was the history mechanism born. Enabling History Nowadays shells like ksh support a history mechanism that can visually modify the command line, allowing the user to edit the command line, call up previous commands by pressing the up arrow. The C shell does not do this. It was designed for any terminal, including the prehistoric hard-copy terminals. The C shell has no problems running within Sun's cmdtool , for instance. You can make this number bigger or smaller.
But the larger the number, the more memory the shell uses. The command "history" will print out the history information. If you specify a number such as 20, it will list the last 20 commands. The history command normally adds a number before each line for reference.
The "-h" turns this off, so it can be source d. You can reverse the order by adding a "-r" to the history command. The "source -h" command reads the file in, but does not execute the commands. Automatic History Saving You can automate this. The "savehist" variable specifies the number of lines to remember. Large values of savehist will slow down the C shell during the start-up process.
Changing your prompt The C shell numbers each command for reference. Many people like to see these numbers automatically. The C shell allows you to put this number into the prompt. Placing the magic character "! Add a number afterwards, and it limits the list to that number of commands. Some people create aliases to make it easier to view the history: alias h history or alias h "history 20" alias H "history more" Repeating Past Commands The history mechanism isn't just used to keep track of your past commands.
You can execute them again very easily. The command!! Besides repeating the same command, it can be used in other ways: ls file?
If you know the number in the history list or the number that was in the prompt , just specify the number. Suppose the history command listed the following: 31 vi file1. The command "! Remember, the position is relative. So you can guess the relative position, and if you get the wrong command, type the same history command, and you will execute the next one in the list.
A third form uses the first few letters of the command. To repeat the vi command, you can use! The first matching command, searching backwards, is executed. This is my favorite method. It is not necessary to know the number, or to list the history. Suppose you typed the following commands: make prog1;. For instance, the command! To execute the first make command, without knowing the number, you can tell the C shell to search for a string, and execute the command that contains the string.
This is done with the special pattern "? Appending to a previous command Often I find myself executing a command, and wish to repeat the previous command, but append something to the end.
Just execute the "!! This is why you cannot search for a command that contains a space. I often develop complex filters on the fly. I type a command, and add filters one step at a time.
Here is an example, where I want to find all lines that contain "keyword" but not "ignore. The following will print files "prog" and "prog1" lpr prog!! This is no problem if you want a space between the old command and the new word. If you edited file1. You can't type! There are two solutions. The first is to execute the vi command again, and then append a "1"! The C shell history mechanism has a similar feature.
To append the number "1" to the previous vi command, type! That is, you can use the curly braces to enclose the history specification:! You can also use it to repeat words. The special variable "! This is very useful, if you want to save keystrokes. That is, instead of typing touch File cp File File. There is another mechanism for specifying part of the argument list. A hyphen can specify a range. Put a number afterwards, and it places a limit on the range: ls f1 f2 f3 f4 f5 f6 f7 f8 f9!!
Next month I will discuss more elaborate variations. Notice that "! For instance, to repeat the command containing "ABC" type:!? It doesn't matter where the string "ABC" is on the line, the command will be executed again. But sometimes you don't want to execute the command again. You just want to use the word. You could type! You could type history grep A and then repeat the command. Or you could search for that line, and print the line out without executing it, by typing print the command containing "A" echo!?
In other words, you can search for the line, extract the word, and use it in one step: lpr!? Someone onced asked me if there was a way to do this with a function key. They kept pressing the backquote by mistake. If this was done in a shelltool window, there is a solution. Place the following in your. You can also use this to duplicate other common operations. Alas - this only works with shelltool and not in cmdtool mode. One more thing, recent versions of Solaris do not require you to type the second up-arrow.
Word Modifiers in History Last month I discussed the history mechanism. I showed how you could use it to execute commands without typing the entire command again, by using the "!
Different characters can be used, by modifying the value of the histchars variable, which has the default value of "! I discussed event designators last month. These correspond to lines typed at the keyboard. The current command! The last command s! This is a feature of newer versions of the C shell. It matches the current line. It isn't much used unless you use some of the features described below. That's real useful. Word events The previous events refer to complete lines. You don't have to recall previous lines, and use the entire line.
You can just use part of the line. Last month I discussed four word designators. All five examples below are identical: program arg1 arg2 now print arg2 lpr! Just specify the number: lpr! Two different syntaxes exist, because you can use these word modifiers to refer to any command stored in the history memory. If the history contained the following command: cc -o prog prog.
If the value after the hyphen is omitted, the defaults is the next to last argument. I should also mention that the rules for abbreviations are confusing. For instance, to make an alias so that compile xyz does the same as cc -o xyz xvz. Wait till you learn about variable modifiers. Variable Modifiers The C shell has variable modifiers, that can be used to extract part of a variable. That is, if a variable "x" has the value "file. These variable modifiers can be used for variables, arguments, history and aliases.
Let me give some examples. If you wanted to rename all files with the extension ". The abbreviation is longer than typing "file. I tried it, got a segmentation fault, the shell exited, and my window disappeared. It's so much fun researching these little-used features.
Using "! Go figure. You can use ":p" as a "print, but not execute" modifier. If you wanted to see the command that started with "abc" but did not want to execute it, you could type: echo! Just type! This modifier isn't useful for the other cases. If you can find a use for variables, arguments or aliases, let me know. If you wanted to change "old" to "new" in a filename, use! Any character can follow the "s" character; it is used as the delimiter. Note that "!!
The string substituted is not a regular expression. The characters are ordinary. Suppose you typed echo abc. This will be the same as typing cc -o program trial. Instead of typing program abc. This only changes the first occurrence in each word. If present, then the change is made several times in each word. If your shell has this, you could change all lower case "a's" to upper case "A's.
The Bourne shell will echo "? If you wanted to pass it to a second script, and wanted to retain the meta-characters like "? But what would you do if you wanted to separate the words into arguments, but leave the question mark alone?
You could use the nonomatch variable:! The End of History? There are a few more points to mention. You can have multiple variable modifiers on a single variable. In some cases, braces are needed to specify the variable part. In complex cases, the tcsh variant of the C shell behaves differently.
Well, that is everything I know about the history feature of the C shell. It is confusing, but I tried to come up with examples of all of the main features. I hope you found this interesting. C shell Aliases I'm lazy. If there is something that I do on the computer a lot, I look for ways to make my life easier. If there is something that takes ten seconds to type, I'll do whatever it takes to save nine seconds of those ten, even if it takes me days to accomplish this. Weeks, even.
Not quite. I'm not compulsive , you know. Don't be silly. C shell users have a very important tool to save those extraneous seconds: aliases. There are several alternative techniques to save keystrokes. In the last two columns I discussed the history function in detail. You can also create shell scripts. However, shell scripts run in a new shell process. You cannot use them to change your current shell process. Most of you have tried this, by creating a script that says something like:!
The current shell executes a new shell, which changes its directory. However, this shell, being a child, does not affect the parent shell. Another technique is needed. The third method is to use variables as commands.
Many people forget about this particular approach. This makes the syntax more complex. This makes it difficult to document complex aliases, and multiple-lined aliases must have the newline quoted. Using these in aliases require additional quoting, adding more complexity. Bourne shell functions were added long after C shells had the alias. They act like aliases, but do not suffer from the above problems.
All-in-all, the concept of C shell aliases is flawed. They are fine for simple definitions, but if you need anything more complex, I suggest you use a shell script in whatever shell you prefer or define an alias to source the script, as I did above. A file for aliases I have the following in my. This isn't high security, but I no longer wake up screaming in the middle of the night. You can make sure that you only read this file once, by using a special variable: if!
But remember that if you change to another user ID, like the superuser , these aliases may not be there. Hi You might find it very trivial but actually don't know how to loop through all sub-directories and their child directories into a csh.
Using the Foreach loop, Needing help. I am trying to make a script for my Counter-Strike: Source servers. What i am wanting it to do is for it to restart each server, the only way i can think of doing this in through for each. Years what i have at the moment. Foreach loop that skips the header line of a file csh. Hello all, I'm working on a foreach loop to compare a couple sets of data.
However, each datafile includes a header row. I'm wondering if it is possible to tell the foreach loop to skip the first line of data. How to loop Iterate through List with foreach csh. Hey all,, I know cshell is harmful: but I am using this just "to know" - for educational purposes!
I'm confused as I never specified checking for the files. Hi everyone Does anyone know what is wrong with this script. Hi Guys, I have a loop which uses a wildcard i.
Foreach loop. What am I doing wrong with this foreach loop? Hello, I am new at this forum so please bare with me on this. Within a given directory, I have a list of files in which in each file, I would like to do a substitution. I would like to substitute the string mlcl to mll in each file using the foreach command. I dont quite get how to do that. RedHat Commands. OpenSolaris Commands. Linux Commands. SunOS Commands. FreeBSD Commands. Full Man Repository. Advanced Search.
0コメント