Prompt is different in midnight-commander (mc) subshell - prompt

The problem first:
The subshell of mc has a different prompt compared to the parent shell and my tcsh environment. All the other settings/variables/aliases are available in mc's subshell, only the prompt is not "passed" correctly it seems. I have no idea why that happens.
Man page says:
An extra added feature of using the subshell is that the prompt displayed by the Midnight Commander is the same prompt that you are currently using in your shell.
Background:
I am using mc.4.8.23 which I have installed on my own locally (because no root permission). Did basically those two steps:
./configure --prefix=<absolute path>/eda_tools/mc/mc-4.8.23/install --bindir=<absolute path>/eda_tools/mc/mc-4.8.23/bin --with-screen=ncurses
make install
Rest of mc works fine.
What I have tried so far:
putting a test prompt and a test alias into tcshrc within ~/.config/mc & ~/.mc & ~/.local/share/mc. None of those locations seem to be evaluated at mc startup. I can neither see a changed prompt, nor the test alias.
Have temporarily changed the prompt within .cshrc to a very simple one. Did not help.
changing the prompt on-the-fly within the mc's subshell does temporarily work. So it seems, that the prompt string itself is OK and understood.
Does someone has an idea?

Try to put your tcshrc with prompt settings in ~/.local/share/mc/ directory.
I can't verify with tcsh, but this location definitely works (with bashrc) for bash subshell in mc.

The prompt for tcsh is hard coded in the source file src/subshell/common.c in function init_subshell_precmd. To keep your prompt recompile mc with this patch applied:
--- src/subshell/common.c.org 2019-06-16 19:49:31.041841616 +0200
+++ src/subshell/common.c 2020-01-12 14:17:03.928956667 +0100
## -886,7 +886,6 ##
case SHELL_TCSH:
g_snprintf (precmd, buff_size,
"set echo_style=both; "
- "set prompt='%%n#%%m:%%~%%# '; "
"alias precmd 'echo $cwd:q >>%s; kill -STOP $$'\n", tcsh_fi
break;

Related

linux "enable -n xxx" command works in terminal but not when put into a script

I've found a very strange issue, when in linux terminal I type "enable -n trap", it would disable the trap linux builtin command. But if I put it into a script like
#!/bin/bash
enable -n trap
and then run the script, there's no error but the command is also not disabled. Really appreciate if someone could share what is happening and how to run it in some file instead of directly in the terminal. Thank you!
The enable command only affects the current shell. When you run a script, that script is executed in a new process, so:
A new shell starts
The enable command runs and disables the trap command in that shell
The shell exits
If you want to affect the current shell, your only option is to source the script using the . (or source) command. If the script is named disable-trap.sh and is in your $PATH, you can run:
. disable-trap.sh
You can also provide a full path to the script:
. /path/to/disable-trap.sh
Sourcing a script like this is largely equivalent to typing the same commands in at the command line: it executes the instructions in the script in the current shell, rather than spawning a new process.

How to identify which REPL is running in the terminal?

I am trying to have my terminal title change depending on what that specific window is doing. So far I have the following which will update based on directory and server.
function settitle() {
if [[ -z "$ORIG" ]]; then
ORIG=$PS1
fi
TITLE="\[\e]2;$*:$(dirs -0)\a\]" #dirs -0 is like pwd but with ~/ instead of /home/user/
PS1=${ORIG}${TITLE}
}
PROMPT_COMMAND="settitle local" # local is the server name in this case
Now, sometimes I'm in the PHP (php -a) or MySQL (mysql -u user -ppass) REPL, and I'd like the title to reflect that instead of just being whatever directory I launched the REPL from.
The best I can figure is getting the last command somehow, then figuring out what the first word is, and running an if check in settitle(). I've tried everything from here and here among other places, and while I can usually get part of it to work in the command line, non of it works in settitle(). For example.
local:~$ echo 'foobar'
foobar
local:~$ !:0
echo
# I add echo !:0 to settitle()
local:~$ source .bashrc
!:0
local:~$
A note: It should be "source", or at least "echo" from before. !:0 does not recognize itself as a command so it will repeat the last real command over and over. The "!:0" being echoed is a literal string, not the results of the command. Additionally, saving to a var does not work, and just putting the command without trying to echo/save the result gives !:0: command not found.
I don't want to make this an XY problem, so if I am barking up the wrong tree here at any step of the process, please let me know. The goal is to be able to change the title of my terminal window if I enter an REPL. How can I identify when a command will enter me into one?
Note that PROMPT_COMMAND and similar shell features are not relevant when you're in a different REPL; from the point of view of the shell, the entire REPL session is one single command. The shell prompt doesn't show up again until you exit that REPL, and that's the point at which PROMPT_COMMAND and friends are activated.
One thing you can do is alias the command you use to start the REPL so that it sets the title of the window first:
alias phpa='setttitle PHP; php -a'
alias mysqli=`settitle MySQL; mysql -u "$USER"'
or something like that.
The sequence goes like this:
PROMPT_COMMAND runs.
The shell prints its prompt.
You type the command to start a REPL
You are in the REPL. The prompt you see is printed by the REPL, not the shell, which is not involved at this point. The shell is just hanging out waiting for you to exit the REPL; it's not printing any prompts, so it's not ever running PROMPT_COMMAND.
You type commands in the REPL. No matter how many you run, it's part of a single session that the shell sees as a single command.
You exit the REPL.
PROMPT_COMMAND runs.
The shell prints its prompt.

"Ping" causing "command not found" in Cygwin part-time

If I launch Cygwin using the Start Menu shortcut it created, I have access to ping and inetutils. However, if I launch Cygwin directly from C:\Cygwin64\Bin\mintty.exe then there's no ping to be had; not the "socket operation not permitted message" you'd get from a non-admin launch, I get the one you'd receive if ping wasn't installed at all.
Am I overlooking something? The only switch in the shortcut is "-i /Cygwin-Terminal.ico", and manually adding that to a shortcut I create myself doesn't rectify the situation. This is occurring on Windows 8.1 Pro in an admin account.
Running mintty without arguments will run your $SHELL but not as login shell, which won't set PATH etc.
From mintty documentation synopsis and invocation:
mintty [OPTION]... [ - | PROGRAM [ARG]... ] [...]
If a program name
is supplied on the command line, this is executed with any additional
arguments given. Otherwise, mintty looks for a shell to execute in the
SHELL environment variable. If that is not set, it reads the user’s
default shell setting from /etc/passwd. As a last resort, it falls
back to /bin/sh. If a single dash is specified instead of a program
name, the shell is invoked as a login shell.
So, the following should get you going, it worked for me.
c:\cygwin64\bin\mintty -
That is, invoke mintty with - as parameter

Missing gem after changing shell to ksh

my MAC is getting hair-wired after I change console to ksh, and change it back again to /bin/bash
the console prompt is now static bash-3.2 regardless current directory I am in. Meanwhile in .bash_profile I have set # modify console
export PS1="\W > "
rake gem and few others in Ruby are missing, although it was reinstalled again after I run bundle install , but there are subsequent strange issue, e.g. rake command does not hit the right rake file..
Any idea?
Thanks a lot.
The .bash_profile is only run by bash when you first log in. (It only gets run by Terminal if you have Terminal set up to make each shell a "login shell"). If you have commands that you want to get run every time you fire up bash, even if it's not a login shell, you should put them in .bashrc instead. But you can always make a shell be a login shell by running bash --login instead of just bash.
Not sure where your ksh comes from, but note that it doesn't understand '\W' etc in the prompt string, so I would expect you to get a literal '\W' in the prompt instead of the expanded working dir. If you're running ksh as a login shell, it's probably something in the .profile (or /etc/profile, etc.). ksh doesn't have an exact equivalent of .bashrc, but if $ENV is set to a filename after the profile runs, that file is executed as well (even on non-login shells, if ENV is already set when the shell starts). Ksh, of course, ignores .bash_profile and .bashrc.
Since there's no ref to gems in the body of your question (anymore?), you might want to change the question and remove the Ruby tag...

How can I debug the bash prompt?

I've been editing .bashrc files and other init files, and it seems that I've left behind a few code snippets or two that are causing a few errors at the prompt (e.g. file missing), but I can't find them.
How do I debug the prompt to find out what init scripts I've carelessly hacked?
Most of the shells have debug flags that show the commands being executed. Bash may even have one that shows a command before expansion of variables and after. Have you tried checking (I believe) -c -x or -X flags and see if they show the information you are looking for.
You can set them as first thing in the rc files (most global one) or just pass it down into bash command by invoking it from another shell.
In fact, if you invoke bash from another shell, you can also use script command to record everything you see and do into the file, which makes postmortem analysis so much easier.
Try invoking bash with the -x flag, then sourcing your .bashrc or .bash_profile or whatever you're using. That ought to be prolix enough to find your problem
ie:
bash -x
source .bashrc
The easiest way to get a clean initial state is to SSH into your current host, but instead of letting SSH launch your shell with default settings, you provide an explicit command which prevents .bashrc from being read.
ssh -tt localhost /bin/bash --norc
The -tt forces SSH to allocate a TTY, which is what would normally happen when you open a shell connection, but is not default when running an explicit command.
The --norc prevents bash from reading your settings file (since we want to do that ourselves).
You should now be at a bash prompt, in a clean environment. This is useful for examining what variable are set to before your .bashrc runs etc. Enable tracing and source your .bashrc:
set -x # Enable tracing
source .bashrc
Try to see where you've defined prompt - probably it in some dot file in your home directory:
grep PS1 ~/.*
You can see current value of prompt by just printing it:
echo $PS1
HTH
Check the .bash_history file in your home directory to find out what commands you have been running. If you used commands like vi filename to open the init scripts, it will find them in the command history.

Resources