PR

FreeBSD ksh setup

FreeBSD
記事内に広告が含まれています。

The original Japanese version is available here.

Last Sunday was Mother’s Day and for the first time in a long time I went for a drive with my mom. I have always liked to drive around, but on the day we were planning to go for a drive, my wife was going to the gym, so we decided to drive alone. While we were thinking about where to go after we started the car, we came to the Chugoku Expressway and saw a sign .. “Tokushima, this way!” after driving for a while. The car was driving for a while, and then we turned the steering wheel to the left and drove around Awaji Island on a mostly local roads. I remembered my friend saying that onions were expensive these days, so I decided to buy a large bag of onions on the road, but they were not as cheap as I thought they would be, and the price was not much different from the price at a slightly cheaper super market near my house, so I ended up buying an assortment of Awaji beer as a souvenir 🙂

Now, we have previously changed the login shell from /bin/sh to /bin/ksh (actually it is /usr/local/bin/ksh, a symbolic link from /usr/local/bin/ksh). Let’s make /bin/ksh a little easier to use this time. There are two major customizations when customizing a shell, not just /bin/ksh

ENVIRONMENTAL VARIABLES

Environment variables are a way to control the behavior of an application by setting its variables appropriately. To see what variables are set by default, log in to FreeBSD and run the set command. You will see what variables are currently set.

Environmental Variables

Here are some typical variables.

LANG

The LANG variable is a variable that allows you to change the language of the messages displayed. It is also referred to as the locale setting. By default, it is set to C.UTF-8. This means that messages are displayed in the system standard language, i.e., American English. There are three different locales related to Japanese. A list can be found with locale -a, so let’s pick up only those related to Japanese.

Although the messages look the same with LANG eucJP or UTF-8, they actually generate different codes. However, Tera Term understand that both EUC and UTF-8 are Japanese and maps them to the correct fonts.

The octal dump of EUC and UTF-8 locale. The SJIS locale seems to be exist as a locale. But message doesn’t seem to be implemented.

This part of Tera Term makes that decision.

The language recognition setting in Tera Term.

If you tamper with this setting, Japanese messages will not be displayed correctly. For example, if you set the language to UTF-8

Set the Tera Term locale to UTF-8, for example.

Then it will not understand anything other than UTF-8.

We see garbage characters if we set the Tera Term locale to UTF-8.

However, other languages are understood correctly as long as they are UTF-8. I didn’t have a very good simple example, but I did have a Chinese message.

Is this Chinese message correct as “No such file or directory” in English ?

According to the FreeBSD manual, the recommended method is to create a non-English class in /etc/login.conf based on default and specify it in /etc/master.passwd, rather than setting environment variables on an individual basis. In case of Japanese, create a Japanese class and create a database file using the cap_mkdb command.

Create Japanese login class.
update the database file and edit /etc/master.passwd file with vipw command.

Specify class with vipw command.

Specify Japanese class for myself.
it works like this.

Since /etc/login.conf is the default setting, its settings can be overridden by individual settings. For example, we changed the default to Japanese in previous step, but we can change it to Chinese, for example, in individual settings.

The individual settings have higher priority than the default settings.

I am not criticizing the idea of creating a separate class field in /etc/login.conf and embedding it in the master.passwd, but if you later try to manage users in M$ Active Directory, you will have problem with handling this class field in master.passwd. So, if you want to manage users locally on FreeBSD, it is easier to specify a class field for each user, and if you want to manage users in M$ Active Directory, it is easier to use the default class field in master.passwd, and set the LANG variable for each user. In a multinational company like ours, even people in the Brazilian office do not necessarily speak Portuguese. Some may speak Spanish, as in neighboring countries. So, we do not change the default locale and leave it as English and each person changes it as needed. I mean, basically everyone speaks English anyway 🙂

PAGER / EDITOR

The PAGER variable allows some application to display a long text file using the pager command set in the PAGER variable. For example, if PAGER is set to less and we type “man ls”, then ..

We can read man pages using less command. Another example, with more command, it would be

temporarily set more in PAGER variable.
The pager command is set to “more” command.

As specified, more command is used. Commands other than the pager may also be specified. For example, wc command can be used.

We could see the total line number of “man ls”. The EDITOR variable is similar to PAGER and it allows you to specify an editor command to be started by default, such as vipw command explained in the LANG variable part, which starts the vi editor since the EDITOR variable is specified as vi. If you specify, for example, emacs, the emacs editor will be invoked alternatively.

BLOCKSIZE

By default, BLOCKSIZE is set to ‘K’. An example of a command which this variable works with is df. If you use the default ‘K’ on a server with a very large file system, the number digits will be too many, so let’s set the appropriate block size.

COLUMNS / LINES

This value will affect the behavior of the full-screen application. For example, if you open a file in a full-screen editor, the screen will behave as if it were 24 lines and 80 columns. The 24×80 comes from the specification of vt100, which is a very famous device called a terminal. 24×80 is the standard because the default terminal type on FreeBSD is vt100. Tera Term also has an option to specify the terminal type.

If you change these values and launch a vi editor, etc., it will behave differently. For example, let’s use half value for both.

use half in vertically and horizontally

I was able to use vi commands using only half of the screen, both vertically and horizontally.

As a side note, the library needed to create an application that handles full screen in this way is called the curses library ( man curses ), and C programs written according to this manual can realize full screen applications. Some people may say, “Why ? We do have X11, don’t we ?”. But for someone like me who does 100% of my system administration with the CLI, this is important. I remember playing a full-screen game called “rogue” in the old days during break times at work. It is not flashy like today’s smartphone games at all, but I still remember it as a game that captured my imagination. I can’t find it on FreeBSD packages or ports today, but I personally think it is a masterpiece of a game using the curses library. If you have time, give it a try.

TERM

This variable is related to the LINES and COLUMNS variables mentioned earlier, but in order to edit text in full screen mode, the control code is output to move the cursor position, and this variable specifies what terminal type is connected at that time.

There is Terminal ID option in Tera Term settings.

If this terminal id and the TERM variable match, it will function properly as a full-screen editor.

What happens if you specify an incompatible terminal?

Let’s try “ibm” for example.

It does not appear to be operating at full screen at all.

I don’t understand what is happening….. use “:q!” in vi command to quit.

However, if there is “IBM” in the terminal id of Tera Term, the terminal will run in full screen by selecting it. This means that the terminal side can correctly recognize the control code issued from the OS side.

The VT series in DEC is standard for a long time.

The typical terminal types in the world are defined in a file called /etc/termcap. Without this file, when you edit a file with vi and move the cursor to the next line after the bottom line, nothing will happen. You would not even be able to move the cursor before that. Because the control code is defined in this file, we have a very complicated control code exchange with the terminal: to display another line on the bottom line, the previous lines are moved up one by one, the line that was on the first line is erased, and so on.

The control code definition for vt100.

PS1

PS1 is the prompt setting for the command line. It defaults to “\u@\h:\w $”. This does not mean that this is the default for ksh, but we are in a situation where ksh is taking over the default for sh. So, if you run /bin/sh on top of ksh, you will see what this spell-like string means.

user@hostname:location

The source code for pdksh shows that the “!” character in the prompt can be changed dynamically at the prompt.

The “!” character in the prompt indicates the number in the command history. So, if you want to run the second command in this example again, use

We can use command history.

and reduce keystrokes.

ENV

The ENV environment variable is a file used to customize the behavior of the ksh command itself. The contents of this file will be explained later.

PATH

The PATH variable specifies the order of the directories, and search entered command in this order. Here is my default PATH for FreeBSD.

What it does is, for example, if you type vim, it looks for the vim command in /sbin, and if not, it looks in /bin, and then looks in /usr/sbin …. /usr/bin … /usr/local/sbin … /usr/local/bin … and finally look for the /home/pokemon/bin directory. If it is not found anywhere, an error message “not found” is displayed. Then, how about vi command?

You go looking for it as you did with vim, and there is a vi command in /usr/bin. So what happens if there are multiple vi commands? I created an empty file called vi in the /home/pokemon/bin directory and gave it execute permission.

If there is no vi command in /usr/bin, then /home/pokemon/bin/vi would be used. But since /usr/bin/vi exists, /home/pokemon/bin/vi is not used. In this way, PATH can be used to specify which directory has priority for a specific command. So, is the order provided by default sufficient? Historically, /usr was often mounted on a separate partition, so /bin and /sbin contain basic commands such as file system repair in single-user mode, and the other commands are often located in /usr/bin and /usr/sbin. Commands installed with the pkg command are also installed in /usr/local/bin and /usr/local/sbin. Finally, /home/pokemon/bin is generally used for commands in development versions of commands you want to put in /usr/local/bin, or for custom scripts you want to use on your own. So, it is logical to put /home/pokemon/bin first, followed by /usr/local/bin, and finally /bin and /usr/bin. Why is /usr in a separate partition? As I remember writing in another article, disks at that time were very small in size, and we normally installed an OS on multiple disk drives. So, in most cases, it was not possible to put everything in the root file system, which is why it was split between /bin and /usr/bin. Nowadays, most systems seem to have only the root file system, swap and boot file system.

Finally, write these desired changes to your $HOME/.profile file. This way, you will not have to re-configure them every time you log in.

I did it this way.

PATH is set in the same order as described earlier, TERM is also explicitly set to vt100, and PS1 is set with system/user information retrieved from the command. This will be a separate article, but when we use M$ Active Directory for user management, We can remove the domain part and also discard the domain part of the FQDN for the hostname. At work, I have a slightly more complex operation in this file in my home directory under my NFS mounted /home. I have many similar Tera Term windows open in my work environment, so I can see at a glance which servers I am connected to and with which privileges. This is (for me) very important, because if you forget about it and copy/paste a wrong string, you may end up with an open mouth 🙂 There are a lot of environment variables, so you can set them as needed.

ALIASES

Now, the second customization is to customize ksh itself. That file is the .shrc file mentioned above. This file is originally for /bin/sh, and the default file name for /bin/ksh is $HOME/.kshrc. This time, since the ENV variable is set, we would like to use the /bin/sh environment as it is. First, open the file with an editor.

This is what it looks like. PS1 in this file is commented out, but nothing changed even though I made changes to PS1 in $HOME/.profile, so I checked and found that the PS1 is set in $HOME/.shrc. So I commented out PS1 in this file by me. The resulting prompt looks like the one above.

For basic customization, I think you should use the alias command so that you can just hit the command as you are comfortable with. In my case, I share my home directory with Linux and other operating systems, so I change commands slightly depending on the operating system.

All system administrations know that it is very easy to destroy a system with wrong commands 🙂 , so it is recommended to keep this “paranoid” part enabled.

When you found you entered wrong command, system says … can I remove these files for you ? You are safe in most of this kind of situations 🙂

After that, just type “man ksh”, look at the manual, and set up the functions you want. In my company’s environment, we have a mixture of FreeBSD and Linux, so it is not as simple as this example, but the basic idea is to ensure the same usability on FreeBSD, Linux, and Solaris as much as possible. The basic idea, however, is to make it as easy as possible to use FreeBSD, Linux, and Solaris in the same way.

Finally, I wanted to have some fun with “rogue” again, so I looked for it: there is no FreeBSD package for it, and it was not in the ports I will discuss in a separate article. After some researching on the net, I found that the original rogue source code is available here. I immediately downloaded and compiled it. First, download the zip file. Then, run configure as usual. I add the option to use ncurses just in case.

Now that configure is complete, try to make it normally.

It is declared that another structure “term” used for the structure “TERMINAL” is missing 🙁

Let’s look at term.h. and the structure “term” seems to be able to use entities if NCURSES_INTERNALS is defined.

Edit the Makefile created by configure command, and then …

Add compile option.

Clean up the object created by make and run make again.

It seems to have passed properly. Let’s run the compiled program.

Oh! It’s the old “rogue” (T T).

For usage, see rogue.cat created by make.

The game is played by walking around inside the caves surrounded by squares and through the passageways between caves, picking up things that have fallen and defeating monsters that appear, and progressing deeper and deeper underground. If you think of Dragon Quest, it is not so far off the mark. If you are interested, please give it a try.

Advertisement below


コメント