Switching between shells

I don't know why, but it just isn't working how I want it to work. You might want to run it to see what I mean. Or you might be a genius (or just really good at unix) and know just by looking at it what the problem is. Have fun trying to figure this one out.:wall:

what do you mean its not working? Post the error and the expected behavior.

tcsh wasn't working, but now I think I got it working. for some reason I had to execute the file directly, just typing tcsh didn't work for me here is the new script.

There's no point to putting bash or ksh in backticks. And exec always has the side-effect of annihilating the program that runs it. Which is fine if that's the last thing your program ever does anyway, but then, why not do it for all options?

1 Like

It is because bash and kcsh open just fine when I put them the way they are, but tcsh just doesn't open the right way. But the program is working, so I am just going to leave it alone until it starts causing me problems. then I just make them all open with exec

I mean that putting them in backticks may have negative side-effects. Do you truly want to capture their output and turn it into an argument? If not, there's no point using backticks and doing so may cause errors later when arguments pop up in places you didn't want them.

Oh ok so basically for the most part backticks are not required. But for some reason, I remember when I was writing another program, I had to put the backticks in or it just wasn't working. Is there a scenario where backticks are required?

You have used backticks probably like below (in echo (print) statement ) but not csh because of its hang may cause of a bug when use bactick with tcsh..
you can maybe update tcsh with related patch or upgrade with a newer version then try again with backticks

#!/bin/bash
clear
echo ".-----------------------------------------------------------------."
echo "| |"
echo "| Please specify which Shell you want to switch to: |"
echo "| 1. Bash |"
echo "| 2. Korn Shell |"
echo "| 3. T Shell |"
echo "| |"
echo "'-----------------------------------------------------------------'"
echo " "
echo "Enter the number of your choice: "; read shell
case $shell in
1) echo "You are now in BASH" ; bash ;;
2) echo "You are now in KSH" ; ksh ;;
3) echo "You are now in TCSH" ; tcsh ;;
esac
clear

regards
ygemici

#!/bin/bash
echo "Please select which Shell you want to switch to:"
select shell in bash ksh tcsh
do
    echo "You are now running $shell"
    exec $shell
done

Backticks have one and precisely one function: They turn a program's output into a parameter or string.

# doesn't work
STRING=programname
# works
STRING=`programname`
# doesn't work
myprogram program-printing-parameters
# works
myprogram `program-printing-parameters`

If you're throwing around backticks everywhere until a program "works" you are misusing them. Only use them where you want to capture a program's output into a parameter or string.

parent shell is waiting for execute of return value (file , command , variable , or any result..) that in backticks expression.firstly a new shell is executed and switching in.in new child shell , but commands are executed that is not efficiently work so does not produce any output.however parent shell is waiting still the result of it's and therefore probably commands can not see on stdoutput in this shell (probably non-access to terminal device via stdoutput because of ` ` backticks are still open so uncompleted and subshell has not it's own stdoutput fd!! )

firstly lets see wait issue effect these with backticks
for this i added the end of file an `echo`

# sed -n '$p' /etc/bashrc
echo UNIX.com

and then execute a new shell

# `bash`

i am in a new shell now
# echo "wheres is results my commands "
nothing displayed..but commands are running!
parent shell is try to execute result in backticks so it will try to execute "UNIX.com" when exit the subshell

# exit
exit
-bash: UNIX.com: command not found

in subshell

# echo "test"

nothing displayed again!.

try vim

# vim /usr/local/bin/test
Vim: Warning: Output is not to a terminal

so vim cant access to terminal , let see so why.

in parent shell

# lsof | grep pts/5 >list

check the shells

Every 1.0s: ps -eo "%p %P %y %x %c %a %t" | grep pts/5|grep -v grep               Mon May  9 22:05:50 2011
17607 12796 ?        00:00:00 sshd            sshd: root@pts/5               01:04:05
17609 17607 pts/5    00:00:00 bash            -bash                          01:04:05
26611 17609 pts/5    00:00:00 bash            bash                              26:52
# grep 26611 list
bash      26611      root    0u      CHR              136,5                   7 /dev/pts/5
bash      26611      root    2u      CHR              136,5                   7 /dev/pts/5
bash      26611      root  255u      CHR              136,5                   7 /dev/pts/5

Besides, as seen in above there is not a map with terminal and stdoutput in new shell with backticks..

last of all , in your script bash and ksh is seem success , csh is hanging (but in fact none of the successful)
as a result backticks are un-needed when they already will execute the commands by current shell.

#!/bin/bash
clear
echo ".-----------------------------------------------------------------."
echo "| |"
echo "| Please specify which Shell you want to switch to: |"
echo "| 1. Bash |"
echo "| 2. Korn Shell |"
echo "| 3. T Shell |"
echo "| |"
echo "'-----------------------------------------------------------------'"
echo " "
echo "Enter the number of your choice: "; read shell
case $shell in
1) echo "You are now in BASH" ; exec bash ;;
2) echo "You are now in KSH" ; exec ksh ;;
3) echo "You are now in TCSH" ; exec tcsh ;;
esac
clear

regards
ygemici

Even better than using backticks, when you want to capture output of command, is $(). Like:

contents=$(ls -a $someDir)

Which is the same as

contents=`ls -a $someDir`

except you can use the $() construct nested, whereas backticks not.