cmderdev / cmder

Lovely console emulator package for Windows
https://cmder.app
MIT License
25.88k stars 2.03k forks source link

fix: /task "<taskName>" no longer works since version 1.3.20 #2806

Closed pulsovi closed 1 year ago

pulsovi commented 1 year ago

Since version 1.3.20, it is no longer possible to launch the "bash::bash" task via the /task "bash::bash" option.

When bash runs in this context, it crashes immediately after the init scripts (/etc/profile, ~/.bashrc, ...) with the message bash: /title: no such file or directory

After a hard investigation, it occurred to me that the command line that invokes the bash.exe process ends now with /title "Cmder".

So bash thinks it should execute the script contained in the /title file, but this file does not exist, hence the error message.

To highlight this, you can add these lines to the end of your ~/.bashrc file:

get_field_number () {
    local string="$1"
    local fieldString="$2"
    local fieldNumber="$(echo "$string" | tr -s " " | tr " " "\n" | grep -m 1 -n "$fieldString" | cut -d : -f 1)"
    echo $fieldNumber
}
get_winpid () {
    local pid="$1"
    if [[ -z "$pid" ]]; then return; fi
    local fieldNumber=$(get_field_number "$(ps)" "WINPID")
    local winpid=$(ps | grep "^\s*$pid\s" | tr -s " " | cut -d " " -f $fieldNumber)
    echo $winpid
}
get_win_ppid () {
    local winpid="$1"
    if [[ -z "$winpid" ]]; then return; fi
    local winPPID="$(wmic process where "ProcessId=$winpid" get ParentProcessId)"
    echo "$winPPID" | head -n 2 | tail -n 1
}
pid="$(get_winpid "$$")"
echo "this process command line and name : "
wmic process where "ProcessId=$pid" get Name,CommandLine
pid="$(get_win_ppid $pid)"
while [[ -n "$pid" ]]; do
    echo "parent pid is $pid"
    wmic process where "ProcessId=$pid" get Name,CommandLine
    pid="$(get_win_ppid $pid)"
done
echo "press any key to continue…"
read -n 1 -s

This script starts by looking for the PID of the bash running on Windows (the PID contained in $$ is a Unix-like virtual PID, it is not the PID that appears in the Windows task manager)

Then it will display the command line corresponding to this WinPID, and loop to do the same work on the parent of bash.exe which is ConEmuC64.exe then on the parent of the latter, ConEmu64.exe.

At this point in time, the Cmder.exe launcher has already exited, so it is not possible to go back any further.

The script ends with a read ... pause command, so you might want to take the time to investigate Windows Task Manager to confirm that it is as I describe it.

The problem is that Cmder.exe now passes ConEmu the /title "Cmder" parameters after the /run {bash::bash} parameter. Which is contrary to ConEmu's instructions in its documentation: ConEmu args

... This must be the last used switch (excepting -new_console and -cur_console) ...