ghaerr / elks

Embeddable Linux Kernel Subset - Linux for 8086
Other
983 stars 106 forks source link

Iterate over string in shell script? #1974

Open RNRetailer opened 3 weeks ago

RNRetailer commented 3 weeks ago

Hi,

How do I iterate over a string in an ELKS shell script?

I found numerous ways that worked in Linux bash but none in ELKS.

I can receive text one line at a time over the serial port but I can't iterate over the characters.

Thanks

ghaerr commented 3 weeks ago

We're running a pretty early version of bash because of size constraints, some of the string variables operations are implemented, but I can't remember which ones. Can you give an example of some working Linux bash shell programming that you'd like to duplicate? We will likely have to look at the source to determine what /bin/sh can and can't do, it lives in elkscmd/ash/var.c and elkscmd/ash/bltin/expr.c.

There are other ways to read the serial port if you want to run or write a program, see sercat (elkscmd/sys_utils/sercat.c).

RNRetailer commented 3 weeks ago

I'd like to get the length of a string and then iterate over it, like this:

foo=string

for (( i=0; i<${#foo}; i++ )); do echo "${foo:$i:1}" done

Thanks

ghaerr commented 3 weeks ago

Dang, our bash doesn't support numeric variables such as in your for loop, nor substrings using ${var:start:len}. Looking at the ash source, looks like it only supports :-, :+, :? and :=, with the colon also optional.

I have a slightly newer version of bash (actually ash) from 1993 instead of our 1991 version I'm looking at, which I have previously considered porting of its parameter expansion over. That version adds support for #, ##, %, %% (pattern matching from left or right), and #parameter (length). It doesn't look like this would help with what you're looking for though.

So unfortunately - there isn't a way to do what you want in the shell at this time.

RNRetailer commented 3 weeks ago

How do I use sercat to receive a file over serial?

I tried this on ELKS:

sercat /dev/ttyS0 > /root/test.txt

Then on the other Linux computer:

cat test.txt > /dev/ttyUSB0
echo -n -e \\x04 > /dev/ttyUSB0

The file /root/test.txt wasn't even created and the echo failed to close sercat.

Please let me know how it's supposed to flow.

Thanks

ghaerr commented 3 weeks ago

How do I use sercat to receive a file over serial?

Sercat sets the serial line in raw mode so sending a ^D won't close the file. The easiest way to make it work is to cat the file over from the remote system to ELKS, then interrupt sercat on ELKS with ^C after the data has been sent, which it catches, which then writes the file.

The likely reason you never saw /root/test.txt created is because ELKS was rebooted without running "sync". The file was created but not synced to disk. This can be made automatic by uncommenting sync=30 (seconds) in /bootopts, if wanted.

RNRetailer commented 3 weeks ago

^C and ^D both failed to close sercat given the above command.

I had to reboot.

Does it work for you?

Thanks

RNRetailer commented 3 weeks ago

Also, what is the command to change the baud rate of /dev/ttyS0 in ELKS?

Thanks

ghaerr commented 3 weeks ago

Does it work for you?

Well - no! Geez, nothing but bugs around here. For some reason (which I'm looking into and will fix) the ^C interrupt from the ELKS console doesn't actually interrupt the sercat read of the serial port until AFTER the next character is received (if there is one, if not, yes - hang forever). Then, while reading the source, I find that you can send ^D (which I tested manually using QEMU) to exit sercat from the remote sending system.

what is the command to change the baud rate of /dev/ttyS0 in ELKS?

stty 19200 < /dev/ttyS0 should work.

ghaerr commented 1 week ago

Hello @RNRetailer,

^C and ^D both failed to close sercat given the above command. I had to reboot.

I have found and fixed this problem in #2001, if you're still interested in trying it out. Are you compiling the system yourself or running from compiled binaries?

The sercat program should now work for you, but only for ASCII (non-binary) data, as a ^D received will terminate sercat.

It seems that Picocom isn't necessarily a quick-and-dirty port over to ELKS. What kinds of files are you trying to transfer into ELKS? I'm sorry to see all these troubles. Perhaps I can help make sercat work for you if this fix doesn't do that.

Thank you!

RNRetailer commented 1 week ago

I'm using the precompiled ELKS v0.7.0

If you make a new release I can test out your new sercat binary.

I was just transferring simple text files to see if I could edit them locally on my 286.

From my testing the included vi didn't really work, but edit worked fine.

Thanks

ghaerr commented 1 week ago

We're not quite ready to cut a new release yet, although one is overdue.

I've attached a 1440k (MINIX) image for you to test, with sercat in /root's directory. It requires this updated kernel in order to work. Let me know how it goes.

From my testing the included vi didn't really work

What exactly? I have no known bugs with vi, but you're doing pretty good finding them!

fd1440.img.zip

RNRetailer commented 1 week ago

That floppy image didn't work for me.

It booted to this message:

ELKS.....*****1!
Press key

I'm using a Compaq Portable III with 286 + 287 and 640 KB ram.

The floppy is a standard 3.5" 1.44 MB.

Thanks

ghaerr commented 1 week ago

I just tried the image again and it is working.

ELKS.....*****1!

The * means disk sector read retry and the 1 means disk read error. I would guess your floppy is bad?