I am not sure if it is a "don't do this" too...
Thanks to the extremely useful discussion in https://unix.stackexchange.com/questions/213799/can-bash-write-to-its-own-input-stream/ ...
The tailcd
utility (for "tail-call cd
") that works both in bash and under the Midnight Commander allows usage in scripts like
/bin/mkcd:
mkdir "$1" && tailcd "$1"
The implementation is tricky and it requires xdotool
. The tailcd
command must be the last command in the script (this is a typical compatibility requirement for utilities that allow multiple implementations). It hacks the bash input stream, namely, inserts cd <dirname>
into it. In the case of Midnight Commander, it in addition inserts two Ctrl+O (panels on/off) keyboard commands and, in a very hackish manner, uses sleep for inter-process synchronization (which is a shame, but it works).
/bin/tailcd:
#! /bin/bash
escapedname=`sed 's/[^a-zA-Z\d._/-]/\\\\&/g' <<< "$1"`
if [ -z "$MC_TMPDIR" ] ; then
xdotool type " cd $escapedname "; xdotool key space Return
else
(sleep 0.1; xdotool type " cd $escapedname "; xdotool key space Return Ctrl+o; sleep 0.1; xdotool key Ctrl+o )&
fi
(The space before cd
prevents the inserted command from going to the history; the spaces after the directory name are required for it to work but I do not know why.)
Another implementation of tailcd
does not use xdotool
, but it does not work with Midnight Commander:
#!/bin/bash
escapedname=`sed 's/[^a-zA-Z\d._/-]/\\\\&/g' <<< "$1"`
perl -e 'ioctl(STDIN, 0x5412, $_) for split "", join " ", @ARGV' " cd" "$escapedname" $'\r'
Ideally, tailcd
would/should be a part of bash, use normal inter-process communication, etc.