Ticket #4521 (closed defect: fixed)
Really escape fish shell history
| Reported by: | htower | Owned by: | andrew_b |
|---|---|---|---|
| Priority: | major | Milestone: | 4.8.32 |
| Component: | mc-core | Version: | master |
| Keywords: | subshell, fish, history | Cc: | johannes |
| Blocked By: | Blocking: | ||
| Branch state: | merged | Votes for changeset: | committed-master |
Description
Some of the "service" commands generated by the mc "leak" into the fish subshell history available to the user. An example to reproduce:
- set user shell to fish and start mc (SHELL=/usr/bin/fish mc)
- navigate to any directory
- press Ctrl+o
- press ↑ button (UP, go back in history)
- observe " cd (printf '%b' ... " command
Older versions of fish shell ignored commands starting with a space (and did not show the discussed cd-commands), but after this issue, fixes were made that emulate the behavior of zsh's HIST_IGNORE_SPACE feature. So, we just have to use the zsh workaround for the fish shell as well.
The proposed patch has been tested with:
- fish shell, version 3.6.1
- mc, version 4.8.27
- mc, 'master' git branch
Attachments
Change History
comment:1 Changed 22 months ago by htower
I'm sorry, I need to further test my fix, because maybe there are some problems that it introduces :(
comment:2 Changed 22 months ago by htower
Added an updated version of the fix.
After a deeper dive, more serious problems of the fish subshell were discovered, namely, incorrect execution of all types of commands coming from the Midnight Commander, not only fs-related "internal" commands (" cd ..."). An example of incorrect operation with a fish sub-shell:
- set user shell to fish and start mc (SHELL=/usr/bin/fish mc)
- type "pwd"
- type "pwd" in the built-in command prompt and press Enter
- repeat entering the "pwd" command several times, 4 for example
- press Ctrl+o
- In the shell output, it can be seen that the command was executed only in half of the cases, for our example with 4 commands there will be only 2 results
Experimentally, I found that for reliable operation, it is enough to add a "dummy" command ("\n", an empty in my fix) as the first one, after which all other sent lines are no longer ignored. This is probably not very nice and correct from a fundamental point of view, but finding the true cause requires significantly more time and effort, most likely you will have to figure out the code of the fish shell itself.
The proposed fix is tested for:
- fish shell, versions 3.6.1 (c++), 3.7.0 (c++), git master (rust)
- mc, version 4.8.30, git master
comment:3 Changed 21 months ago by andrew_b
- Status changed from new to accepted
- Owner set to andrew_b
- Branch state changed from no branch to on review
- Milestone changed from Future Releases to 4.8.32
Thanks!
Branch: 4521_fish_history
changeset:8746c16ac1d7a68d1ac78cdacb639fe6cf5407f7
comment:4 Changed 21 months ago by andrew_b
- Votes for changeset set to andrew_b
- Branch state changed from on review to approved
comment:5 Changed 21 months ago by andrew_b
- Status changed from accepted to testing
- Votes for changeset changed from andrew_b to committed-master
- Resolution set to fixed
- Branch state changed from approved to merged
Merged to master: [dc1aa3e4e30f3f871a57a81cd7aa9156668b3db8].
comment:7 Changed 9 months ago by ossi
my guess would be that there race condition between the shell discarding the input buffer after it displays the prompt, and mc feeding it commands. let's test it:
(echo " echo hello"; sleep 1; echo " echo world") | fish
nope, with fish 3.7.1 this executes both commands just fine.
... but only once the input is closed. this is certainly caused by input buffering of the pipe. and notably, it doesn't let itself convince otherwise with stdbuf, so it's definitely doing something non-standard.
note that fish is the only shell i tried that exposes this behavior - dash, bash, and zsh process the first command right away.
ok, let's try harder, then:
(echo " echo hello"; sleep 1; echo " echo world") | socat - EXEC:'fish -C \"sleep .5\"',pty,setsid,ctty
this reproduces mc's behavior more closely, and it still works just fine.
this experimentation can be taken further, if things still don't work when reverting the hack in mc.
