hello world
BASH only has one okay syntax highligher, but its super slow, it implements the whole readline lib in BASH, so i decided to make my own ... but its harder than i thought
at first, i kept running into issues with file descriptors, bash kept being annoying, kept blocking my stuff, but then i came up with an idea to read from its stdin and then write to stderr and use ansi escapes to move the cursor and text around, it worked kinda ig, but theres a problem, as bash owns the fd it can steal a read() from us and make us not be able to read from stdin anymore, which is painful, the concept program keeps missing bytes, especially if youre typing fast, when youre typing slow its much less noticable
theres also an ansi escape issue with the cursor, it keeps going to its old position, but thats probably because it keeps missing bytes, \r
and/or \n
to be specific, in my case \r
idk why bash reads \r
instead of \n
, but oh well
anyway, heres the concept :
how it works is :
- takes from you the target bash shell pid which you can get by running
echo $$
in the target - opens stdin (
0
) and stderr ( 2
) file descriptors - opens
/tmp/{target bash pid}.bash
as an out file ( as you cant write to bash stdin for it to exec code ) - overwrites the outfile
- loops until stdin is okay to use / open
- writes ansi escape for 'save cursor position'
- while a single read byte from stdin is not
\r
and / or \n
- interprets backspaces
- writes 'restore cursor position' and 'clear line from cursor position' ansi codes plus the highligted line to stderr
- write a newline to stderr
- if s is not empty
- writes the read command to the outfile
- sends a
SIGINT
( basically CTRL
+ C
) signal to bash ( to activate PROMPT_COMMAND and get a new prompt as once again -- bash doesnt like when you use its file descriptors for that )
- at the end of the main loop it closes opened stdin, stderr and out files
on the target side you only need to run this
export PROMPT_COMMAND="source /tmp/$$.bash"
so it runs the command every new prompt as bash should not be able to read the command and we should own it
so far i tried these methods to mitigate the problems i faced :
- using
LD_PRELOAD
to overwrite the read()
syscall - making always return
0
- redirecting it to a FIFO
- closing it
- using
os.write
/ read
- using C++
- using C
any help to resolve the issues is welcome, although its optional, itd just help improve the quality of the concept and make it maybe even useful to people, you can comment here or under the gist ( preferably under the gist ), lets discuss your ideas :) you are also free to email me at ari.web.xyz@gmail.com
anyway, enough talking, i think this will be a multipart series until i make something working or give up, once i get something working ill try to make it easy for others and develop a framework around it, maybe others might too, if you have any ideas how to fix it let me know and well, see you next time :)