I am trying to learn the basics of shell. I used vim editro for creating my own list of commands to be executed. Here is the way I created the code
vi mycommands
then inside this file I wrote
cd Documents
I am using macOS Catalina which has zsh by default but switched to bash
So when I write the following command in the terminal:
$ sh +x mycommands
It shows
+cd Documents
The Documents has some files and directories but it is not changing directory.Where am I going wrong?
Any help will be greatly appreciated.
Scripts run like sh myscript execute in a separate sub-shell, not the current shell. Changing directory inside a script will not cause your shell to change directory. If you want to change directory in your shell, you need to run the commands in your shell.
To do that, run:
. ./myscript (sh, bash) or source ./myscript (bash).
See this question.
When I am running Cygwin.bat I've got my all my custom stuff working from .bash_profile but when I am just running bash none of my stuff from .bash_profile is working and I am just got wired prefix like root#comp:/mnt/c/cygwin64# (as my current dir)
Is there any way to achieve the same result when running bash as I got when running Cygwin.bat
the content of Cygwin.bat is:
#echo off
C:
chdir C:\Tools\cygwin64\bin
bash --login -i
As pointed out by #matzeri in the comment, cygwin.bat invokes bash with the --login option which creates an interactive login shell. And bash without the --login option creates an interactive shell which is not a login shell.
According to bash man page:
When bash is invoked as an interactive login shell, or as a non-interactive
shell with the --login option, it first reads and executes commands from
the file /etc/profile, if that file exists. After reading that file, it
looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and
reads and executes commands from the first one that exists and is readable.
The --noprofile option may be used when the shell is started to inhibit this
behavior.
When an interactive shell that is not a login shell is started, bash reads
and executes commands from ~/.bashrc, if that file exists. This may be
inhibited by using the --norc option. The --rcfile file option will force
bash to read and execute commands from file instead of ~/.bashrc.
My ~/.bash_profile has only one line:
source ~/.bashrc
and I put all conf in ~/.bashrc.
If my current shell is a tcsh shell (confirmed with >echo $shell and >ps $$ etc.), do I have to write shebangs like #! bin/tcsh and have only that kind of scripts to run properly?
I made scripts with sh shebangs #! bin/sh and they run properly, although my shell was always a tcsh shell. My scripts had forloops, which are different in sh and tcsh.
Do I need to change my current tcsh shell into sh shell in order to run scripts with sh shebangs?
Any help?
Thanks!
IF your shebang lines were actually #! bin/sh then the reason that they worked correctly is because that path doesn't exist and your current shell is taking over running of the script.
Fix the path in the shebang line to be a valid absolute path #!/bin/sh and I expect you will see the scripts start to fail.
See http://www.in-ulm.de/~mascheck/various/shebang/ for more about the shebang line that you likely care about.
I am not a Solaris expert and I am trying to create a shell script that will change my prompt to PWD and the ksh to bash and I have this:
PS1='$PWD $ ' exec bash --noprofile --rcfile /dev/null
or
PS1='\w $' exec bash --noprofile --rcfile /dev/null
Both of them dont work from a sh. if i add them from the command line then the first time my bash appears on prompt and the second time the PS1='$PWD $' kicks in and my prompt changes.
Firstly, why is PS1='$PWD $' not working from shell script . and why do i have to run the command from command line twice to acheive my results.
Also, in my export/home/syed/ directory there are three files local.login, local.profile, and local.cshrc. is there any way i can use them that when ever i log in i dont need to run my shell script and upon login i get bash shell and my prompt as i want it
(am i asking too much, i dont like the ksh as it does not have any features like up arrow recall last commands and tab auto complete features)
thanks
Syed...
When you exec from within a script, the script is what is replaced, not the parent shell.
Try sourcing the script rather than running it.
Also, in Solaris, you can use passwd -e to change your login shell.
You may be able to symlink ~/.profile to your existing ~/local.profile (or similar). Note that .cshrc is for the C Shell and is not compatible with ksh or Bash.
If you want that your default shell will be bash, change it in /etc/passwd
When you exec bash it sets up its own environment from scratch. Pass it an --rcfile containing the settings you would like for it to inherit.
How can I tell what type my shell is? ie, whether it's traditional sh, bash, ksh, csh, zsh etc.
Note that checking $SHELL or $0 won't work because $SHELL isn't set by all shells, so if you start in one shell and then start a different one you may still have the old $SHELL.
$0 only tells you where the shell binary is, but doesn't tell you whether /bin/sh is a real Bourne shell or bash.
I presume that the answer will be "try some features and see what breaks", so if anyone can point me at a script that does that, that'd be great.
This is what I use in my .profile:
# .profile is sourced at login by sh and ksh. The zsh sources .zshrc and
# bash sources .bashrc. To get the same behaviour from zsh and bash as well
# I suggest "cd; ln -s .profile .zshrc; ln -s .profile .bashrc".
# Determine what (Bourne compatible) shell we are running under. Put the result
# in $PROFILE_SHELL (not $SHELL) so further code can depend on the shell type.
if test -n "$ZSH_VERSION"; then
PROFILE_SHELL=zsh
elif test -n "$BASH_VERSION"; then
PROFILE_SHELL=bash
elif test -n "$KSH_VERSION"; then
PROFILE_SHELL=ksh
elif test -n "$FCEDIT"; then
PROFILE_SHELL=ksh
elif test -n "$PS3"; then
PROFILE_SHELL=unknown
else
PROFILE_SHELL=sh
fi
It does not make fine distinctions between ksh88, ksh95, pdksh or mksh etc., but in more than ten years it has proven to work for me as designed on all the systems I were at home on (BSD, SunOS, Solaris, Linux, Unicos, HP-UX, AIX, IRIX, MicroStation, Cygwin.)
I don't see the need to check for csh in .profile, as csh sources other files at startup.
Any script you write does not need to check for csh vs Bourne-heritage because you explicitly name the interpreter in the shebang line.
Try to locate the shell path using the current shell PID:
ps -p $$
It should work at least with sh, bash and ksh.
If the reason you're asking is to try to write portable shell code, then spotting the shell type, and switching based on it, is an unreliable strategy. There's just too much variation possible.
Depending on what you're doing here, you might want to look at the relevant part of the autoconf documentation. That includes an interesting (and in some respects quite dismal) zoology of different shell aberrations.
For the goal of portable code, this section should be very helpful. If you do need to spot shell variants, then there might be some code buried in autoconf (or at least in one of the ./configure scripts it generates) which will help with the sniffing.
You can use something like this:
shell=`cat /proc/$$/cmdline`
Oh, I had this problem. :D
There is a quick hack, use ps -p $$ command to list the process with PID of the current running process -- which is your SHELL. This returns a string table structure, if you want, you can AWK, or SED the shell out...
The system shell is the thing you see when you open up a fresh terminal window which is not set to something other than bash (assuming this is your default SHELL).
echo $SHELL
Generally, you can find out all the constants defined by running
set
If the output is a lot of stuff then run
set | less
so you can scroll it from the top of the command line or
set > set.txt
To save the output to a file.
Invoking a different interactive shell to bash in your terminal does not mean that your system shell gets changed to something else i.e. your system shell is set to bash although you invoke a csh shell from a bash shell just that one session.
The above means that typing /bin/csh or /bin/python in bash or whatever does not set the system shell to the shell you invoked, at all.
If you really want to see the SHELL constant change then you need to set it to something else. If successful you should see the new shell whenever you open a fresh terminal...
It's old thread but...
In GNU environment You can sh --help and get something like
BusyBox v1.23.2 (2015-04-24 15:46:01 GMT) multi-call binary.
Usage: sh [-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS]]
Unix shell interpreter
So, the first line is shell type =)