0

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?

Community
  • 1
  • 1
amflare
  • 4,020
  • 3
  • 25
  • 44
  • Terminal emulators sometimes (often? I don't use a lot of different emulators) provide the option to show the current job name in the title bar with no further shell configuration needed. – chepner Mar 24 '17 at 17:21
  • As an aside, if you don't know which shell you're running with, consider making your code more portable. That means leaving out the `function` keyword (the portable way to define a function is just `funcname() {`, with no `function` preceding), and using `.` instead of `source`. – Charles Duffy Mar 24 '17 at 17:46
  • That said, reading the question, it looks like you're not trying to identify the shell, but trying to identify the parent process. Have you considered just looking up `/proc/$PPID/cmdline`? – Charles Duffy Mar 24 '17 at 17:48
  • @CharlesDuffy - I assume the main shell is bash since I'm using `.bashrc`. I'll give your suggestion a try though. Regarding `/proc/$PPID/cmdline`, I am not familiar with that at all. – amflare Mar 24 '17 at 17:49
  • Sure, but unless I'm badly misreading this question, you're talking about dealing with cases where you have a shell started by a different program. If that program runs `sh`, then you have a different shell that's not bash, no matter how your personal defaults are configured. – Charles Duffy Mar 24 '17 at 17:52
  • @CharlesDuffy - So thats not somthing I can adjust for from `.bashrc`? – amflare Mar 24 '17 at 17:53
  • `$PPID` is the parent process's identity. `/proc` is a Linux virtual filesystem that provides information on processes. `cmdline` is the name of a file in procfs that gives the command line of a program in the same format described in tools like `top` or `ps`. – Charles Duffy Mar 24 '17 at 17:53
  • Correct: You can't reliably ensure that an arbitrary 3rd-party program will run `bash`, and thus that `.bashrc` will be invoked, when it kicks off a shell. **Many** such programs will honor the `SHELL` environment variable, but many also hardcode `/bin/sh` (indeed, `/bin/sh` is even hardcoded in the standard C library -- any `system()` call invokes it). – Charles Duffy Mar 24 '17 at 17:54
  • Ok, but if I am launching the interactive shell from bash (ie through `php -a`), will I still be able to capture anything via `PROMPT_COMMAND` before the shell starts? – amflare Mar 24 '17 at 17:55
  • I think I may have misunderstood your question. I thought you were talking about `php` launching a shell. Are you instead talking about launching a `php` REPL *from* your shell? – Charles Duffy Mar 24 '17 at 17:56
  • ("REPL" stands for "read/eval/print loop" -- it's the traditional/canonical term for an interface where one enters a fragment of program text to be evaluated and run, and useful in this context because that way we're clearly distinguishing whether we're talking about a bash/POSIX-sh/&c. style shell or an interpreter for a non-shell language). – Charles Duffy Mar 24 '17 at 17:56
  • Er... yes. I blame the [PHP manual](http://php.net/manual/en/features.commandline.interactive.php) for this confusion. I can update my question to be more clear. – amflare Mar 24 '17 at 17:59

1 Answers1

0

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:

  1. PROMPT_COMMAND runs.
  2. The shell prints its prompt.
  3. You type the command to start a REPL
  4. 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.
  5. 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.
  6. You exit the REPL.
  7. PROMPT_COMMAND runs.
  8. The shell prints its prompt.
Mark Reed
  • 91,912
  • 16
  • 138
  • 175
  • Will the `PROMT_COMMAND` run before the REPL session launches? Or after it closes? – amflare Mar 24 '17 at 18:16
  • PROMPT_COMMAND runs right before the prompt is printed. Then you type a command, which runs, and only after that command exits does PROMPT_COMMAND run again. If you want the window title to change *while a command is running*, you can't rely on PROMPT_COMMAND to do it. – Mark Reed Mar 24 '17 at 18:40
  • Is there a reason to have that list code-formatted rather than as a typical numbered list? The need to scroll is a bit disconcerting. – Charles Duffy Mar 24 '17 at 20:53
  • None whatsoever, @CharlesDuffy. Corrected. – Mark Reed Mar 24 '17 at 21:10