Solved Why are my Aliases not Accepted? [CSH and SH]

Hello everyone,

I'm following Urban Penguin's (UP) Udemy course on FreeBSD; in module eight he enlightens me on the existence of aliases, a remarkably useful feature. Supplemented by this FreeBSD Wiki on aliases, I tried to follow UP's example and add an alias to the cshell. I open .cshrc, in this case of the root user, and add: alias ls ls --color=always

This is added below a row of aliases already present in .cshrc:

alias h history 25
alias j jobs -l
alias la ls -aF
alias lf ls -FA
alias ll ls -lAF
alias ls ls --color=always

On saving and exiting the document, I perform ls, but this does not automatically perform ls --color, as intended.
I noticed that, apparently, there is an inconsistency between UP's example, and what I see presented in the Wiki. The Wiki is without the "=always" value.
I decided to try the Wiki's example, while also changing the alias name from ls to lsc, just in case setting an alias-ls conflicts with the already extant ls command, present per base install.
I thus try to create the alias as follows: alias lsc ls --color

On exiting and saving the document, I perform lsc, but it is returned that the command is not found.


For a non-root user, I have tried to attain the same effect for the sh/bourne shell; I was adviced elsewhere on the Internet to add the following to .profile in a user's home directory in order to attain an abbreviated ls --color:

I understood I should add the following code, to attain the effect of ls automatically being executed as ls --color:


ls() {
command ls --color=auto "$@"

}

I have not yet been exposed to the coding language presented here, but I assume it is shell scripting, or a specific variant of shell scripting.

On saving and exiting, and executing ls in the user's bourne shell, does not result in the effect of ls --color.

I have verified if whether or not I am in the relevant shell by using either ps -s $$ or echo $SHELL. I verified the correct user via whoami. I did this because I considered that I might somehow not experience the root user's cshell configuration via attaining root and the root shell using su via a wheelgroup user. Of course, optimally, that shouldn't matter, but I just wanted to make sure.
I have also tried opening a new terminal, just in case a new instance would load the altered configuration.


Thank you for bearing with me!

SilverC3ll​
 
put things in quotes.
Here are examples from my .cshrc. Syntax for sh and bash may be different.

alias cd 'cd \!*; echo -n ""' alias vi 'echo -n "";/usr/bin/vi \!*;echo -n ""' alias popd 'popd \!*;echo -n ""' alias pushd 'pushd \!*;echo -n ""' alias su '/usr/bin/su -' alias h 'history 25' alias j 'jobs -l' alias ls '/bin/ls --color=never -hF' alias ll '/bin/ls --color=never -lA' alias cls clear alias emacs '/usr/local/bin/emacs \!*&'
 
put things in quotes.
Here are examples from my .cshrc. Syntax for sh and bash may be different.

alias cd 'cd \!*; echo -n ""' alias vi 'echo -n "";/usr/bin/vi \!*;echo -n ""' alias popd 'popd \!*;echo -n ""' alias pushd 'pushd \!*;echo -n ""' alias su '/usr/bin/su -' alias h 'history 25' alias j 'jobs -l' alias ls '/bin/ls --color=never -hF' alias ll '/bin/ls --color=never -lA' alias cls clear alias emacs '/usr/local/bin/emacs \!*&'
Thank you Mer; I changed my syntax per your advice: alias lsc 'ls --color', but this alas did not work. Of course, I'd also point out the aliases that were already present (per base install, out of the box), such as alias h history 25, that do not follow the quoted-syntax.
Executing h indeed executes history 25. But whatever I put in there, is not accepted, read, or recognized, with or without quotes.

In case it matters, I should have mentioned I run FreeBSD14.0 [on VMWare Player 17], but aliasing must be an old feature, and not being highly sophisticated, the factor of a VM probably may be disregarded.

EDIT: Instead of trying to add an alias for the bourne shell via .profile I used a perhaps more obvious choice, namely .shrc
I noticed .shrc does follow the syntax you (and the Wiki about sh) examplify, in terms of quotes anyway:

# some useful aliases
alias h='fc -l'
alias j=jobs
alias m="$PAGER"
alias ll='ls -laFo'
alias l='ls -l'
alias g='egrep -i'
alias lsc='ls --color'

In bold is my added entry, but alas:

Logan@kungfu:~ $ lsc
sh: lsc: not found



Kindly yours,

SilverC3ll​
 
Saving the document is not all. The shell (whichever) loads that configfile when it starts. You need to start a new shell to test it.
Hello PMc,

Thank you so much.
Kindly forgive my neophyte-haplessness: I opened a new terminal emulator (XFCE terminal); is this not the same as starting a new shell?
The system has also already rebooted quite a few times, long after the aliases had been set in place.

I'm obviously a beginner and am grateful for any assistance I may receive.

EDIT: I don't know why, but after a new boot, now things do work. I'll try to repeat my steps to truly see what caused success and what caused failure.
Thank you for your patience everyone.

All the best,

SilverC3ll​
 
Hello PMc,

Thank you so much.
Kindly forgive my neophyte-haplessness: I opened a new terminal emulator (XFCE terminal); is this not the same as starting a new shell?
That should do, normally. But, does that one run as root (or the intended user)?

There are a few gotchas here. Shells do load different configuration files depending on being the initial shell after login, or being started just upon another in an active login. And this behaviour again differs between sh, csh, bash, ... Also, when switching users with su,there are differences between plain su, su -, su -m, ...
So there are already a lot of options to mess things up. ;)
In an X window manager (or "desktop environment") there is more: the X login runs as root, then it should do a user login, which starts some shell script, which then starts the window manager, which then starts an xterm, which then starts a shell.

What I am doing when I encounter weirdness: I add some "echo this is me" at the place where I change the configuration file - then I can see if the shell comes along and actually executes the file, and when it does. But, keep track and remove these echoes later, because they might break other scripts.
 
That should do, normally. But, does that one run as root (or the intended user)?

There are a few gotchas here. Shells do load different configuration files depending on being the initial shell after login, or being started just upon another in an active login. And this behaviour again differs between sh, csh, bash, ... Also, when switching users with su,there are differences between plain su, su -, su -m, ...
So there are already a lot of options to mess things up. ;)
In an X window manager (or "desktop environment") there is more: the X login runs as root, then it should do a user login, which starts some shell script, which then starts the window manager, which then starts an xterm, which then starts a shell.

What I am doing when I encounter weirdness: I add some "echo this is me" at the place where I change the configuration file - then I can see if the shell comes along and actually executes the file, and when it does. But, keep track and remove these echoes later, because they might break other scripts.
Thank you; indeed, FreeBSD is quite the labyrinth. I've recently been exposed to the nuances between terminal, shell, and terminal emulator. I'm not quite ready to understand it all, but I'll stay headstrong.

Both root's csh and the ordinary user's bourne shell now have their aliases in place.

Thank you for the advice on adding echoes; its a good verification check!

EDIT: Though I may not yet fully understand it, can you give me an example where a simple echo could break a script? I may have misunderstood you, but I interpreted your advice as: add an echo to the relevant -rc.conf file to test if your respective shell is loading your updated -rc.conf file.
Will an echo hello world really bring about disaster?


All the best,

SilverC3ll​
 
Yes and no. We need to distinguish two situations:
  1. A new login. For example, someone walks up to the (text-) console of an idle system, types in username and password. The login process starts the shell, and that new shell (knowing that it is a login shell) then executes the startup scripts. In this case, it is reasonable and common to display some information. Matter-of-fact, it was traditional to display a "fortune", a fun and often insightful little quote. The login program also displays some information, namely the motd (Message Of The Day, which might be something like "the line printer is broken, field service will be here in the afternoon to fix it" or "tomorrow, the Fortran compiler will be upgraded to Pascal, please update your programs accordingly").
  2. The shell being invoked to run a script, or as a subshell, or as part of a silent remote login. For example, say you have a "program" that is installed in /usr/local/bin which is implemented in /bin/sh (or whatever shell you like); it might be something that does a directory listing (like ls) but decorates the output with cute pictures of butterflies and kittens. When you run this program, you want to see the ls output (+butterflies +kittens), but not a "Hallo World" or a fun joke or the daily news from the system administration. The output of this program might even have to be run through a pipe and filtered and post-processed, and a "Hello World" would really get in the way there.
    Or you might be running a complex pipe, where part of the pipe has to be executed in a shell of its own. You really don't want to see "Hallo World" multiple times in the output.
    Even worse: when programs such as scp and rsync copy files between nodes, they usually (always? often?) use ssh as the underlying transport mechanism. So what really happens is that ssh logs in to the remote machine, and then is used as a "tunnel" to transport data between the scp/rsyng program on one side, and its counterpart on the other machine. Printing "Hello World" would really screw this up.
For this reason, all shells I know of have at least two separate login scripts, for example .login versus .cshrc (for csh), and .bash_profile versus .bashrc (for bash), and I can't even remember what they're called for sh, ksh, zsh and all the others. One does all the initialization for login shells (case 1 above), the second for subshells (including non-interactive ones, case 2).

The detailed rules for "which file is called when" can easily be lookup up in the man pages. One thing that can be confusing: in a windowing environment (such as an X GUI), opening a new XTerm may count as a new login, or it may not. And the other thing that can be confusing you already discovered: changing these files accomplishes nothing, until the next time you log in or start a subshell.
 
Yes and no. We need to distinguish two situations:
  1. A new login. For example, someone walks up to the (text-) console of an idle system, types in username and password. The login process starts the shell, and that new shell (knowing that it is a login shell) then executes the startup scripts. In this case, it is reasonable and common to display some information. Matter-of-fact, it was traditional to display a "fortune", a fun and often insightful little quote. The login program also displays some information, namely the motd (Message Of The Day, which might be something like "the line printer is broken, field service will be here in the afternoon to fix it" or "tomorrow, the Fortran compiler will be upgraded to Pascal, please update your programs accordingly").
  2. The shell being invoked to run a script, or as a subshell, or as part of a silent remote login. For example, say you have a "program" that is installed in /usr/local/bin which is implemented in /bin/sh (or whatever shell you like); it might be something that does a directory listing (like ls) but decorates the output with cute pictures of butterflies and kittens. When you run this program, you want to see the ls output (+butterflies +kittens), but not a "Hallo World" or a fun joke or the daily news from the system administration. The output of this program might even have to be run through a pipe and filtered and post-processed, and a "Hello World" would really get in the way there.
    Or you might be running a complex pipe, where part of the pipe has to be executed in a shell of its own. You really don't want to see "Hallo World" multiple times in the output.
    Even worse: when programs such as scp and rsync copy files between nodes, they usually (always? often?) use ssh as the underlying transport mechanism. So what really happens is that ssh logs in to the remote machine, and then is used as a "tunnel" to transport data between the scp/rsyng program on one side, and its counterpart on the other machine. Printing "Hello World" would really screw this up.
For this reason, all shells I know of have at least two separate login scripts, for example .login versus .cshrc (for csh), and .bash_profile versus .bashrc (for bash), and I can't even remember what they're called for sh, ksh, zsh and all the others. One does all the initialization for login shells (case 1 above), the second for subshells (including non-interactive ones, case 2).

The detailed rules for "which file is called when" can easily be lookup up in the man pages. One thing that can be confusing: in a windowing environment (such as an X GUI), opening a new XTerm may count as a new login, or it may not. And the other thing that can be confusing you already discovered: changing these files accomplishes nothing, until the next time you log in or start a subshell.
Hello Ralphbsz; thank you for your lengthy and indepth response. Your words were very clarifying and I now understand this principle a lot better. I, of course, will need hands-on experience to truly apprehend your and PMc's wisdom on a practical level. I'm not quite there yet; still assimilating the fundamentals of FreeBSD. I really appreciate the help that is offered along the way.

Yours sincerely,

SilverC3ll​
 
You can load those files "on-the-fly" if you source them. This should work for both the C shells and Bourne shells. source ~/.cshrc for example, or source ~/.profile.
 
You can load those files "on-the-fly" if you source them. This should work for both the C shells and Bourne shells. source ~/.cshrc for example, or source ~/.profile.
Thank you SirDice; I could not run source in the bourne shell but could in the cshell. However, quite logically, the cshell threw back a few errors when I tried to apply it to .shrc.

EDIT: This worked:

In csh: use source as in: source ~/.cshrc
In sh: use . as in: . ~/.shrc


Thank you and kindly yours,

SilverC3ll​
 

Attachments

  • Screenshot 2024-01-15 115053.png
    Screenshot 2024-01-15 115053.png
    538 KB · Views: 193
Right, sh(1) doesn't seem to have it, bash(1) does. You can use a . (dot) instead; . ~/.shrc (note the space between the dot and the filename).

the cshell threw back a few errors when I tried to apply it to to .shrc.
Yes. You're entering sh(1) commands in the C shell, that obviously doesn't work. The ~/.shrc is specific for sh(1).

"Sourcing" a script is the same as entering those commands on the command line itself. This is different from executing such a file (which would spawn a subshell).
 
"Sourcing" a script is the same as entering those commands on the command line itself. This is different from executing such a file (which would spawn a subshell).
And executing a script in order to get the effects of settings is another mistake that beginners make all the time (and experienced users make occasionally):

Say you have changed .shrc to add the "elephant" option as default to ls, by defining "alias ls = ls --elephant" (it causes elephants to fly around the screen whenever you execute ls). Great, now you want to test it. You do "./.shrc" or just ".shrc" (note: no spaces in front). That starts a new subshell, which executes .shrc (meaning it now knows that you like elephants), and exits. Then you try to do ls on the command line, and don't get elephants. Why not?

Because the new settings took effect in the subshell only, which was extremely short-lived: it performed the commands contained in the .shrc file, and exited, without ever running ls. If you want those commands (like that alias described above) to take effect, you need to source the file, without creating a new subshell. Therefore, you do ". .shrc" or "source .shrc" (if available).

There are interesting variations of this mistake. For example, yesterday night I was editing the configuration files for my web server at home (apache's httpd-ssl.conf, which is awfully complex). And about half the time after changing something, I forgot that I need to restart the apache server for the new configuration to take effect.
 
In sh: use . as in: . ~/.shrc

It took a while for that to make sense to me.

Code:
% $EDITOR /tmp/nonsense

% sh
$ echo $EDITOR
/usr/local/bin/nano
$ . /tmp/nonsense
$ echo $EDITOR
/usr/cloud/microsoftword
$ . ~/.shrc
$ echo $EDITOR
/usr/cloud/microsoftword
$ . ~/.profile
To read a compressed file without having to first uncompress it, use
"zcat" or "zless" to view it. There is also "bzcat", "bzless", "xzcat"
and "xzless".
                -- Dru <genesis@istar.ca>
$ echo $EDITOR
/usr/local/bin/nano
$ less ~/.shrc
$

From the manual page (with some fakery, for the first column to be cosmetically OK in XenForo):

. fileThe commands in the specified file are read and executed by the shell. The return command may be used to return to the . command's caller. If file contains any ‘/’ characters, it is used as is. Otherwise, the shell searches the PATH for the file. If it is not found in the PATH, it is sought in the current working directory.

(I would not have made sense of that part of the page, without an example.)
 
Back
Top