4 ms·
> E.g. using vim as editor, the modified file is actually written as a new file under the same filename. I don't know much about the internal workings of vim,
by usefulcat 7y ago
> E.g. using vim as editor, the modified file is actually written as a new file under the same filename.
I don't know much about the internal workings of vim, but I do know two things:
1) I use vim exclusively (on linux anyway).
2) I have been bitten by this exact problem.
I guess I can understand why bash works this way.. it means that it can handle arbitrarily long scripts without having to read the entire script into memory at once. But purely from an everyday usability perspective, this is a really bad design decision. Anyone know if there's a way to force it to read the whole script into memory on startup?
- fl0wenol 7y agoWhen writing a long script you should bundle everything into functions and then call one that kicks everything off at the end. This prevents the problem mentioned but also is helpful for keeping it organized.
- firethief 7y agoI'm surprised that helps. Instead of the seeking behavior demonstrated in the `strace`, does it switch to another way of keeping state after a backward jump? It would also have to buffer the whole file even though it's painstakingly executing it in a way that doesn't require a buffer.
- fl0wenol 7y agoThe parser copies the body of functions and aliases (and heredocs, duh) into memory and interprets it from there. This is necessary because otherwise a function that is called frequently would translate into a lot of system calls for file I/O. Also bash has to work with streams that are not seekable, like piped command output, and so it allows declarations that can be parsed and then later referred to in one pass.
- jolmg 7y agoI would imagine it's the same thing. It's going by top-level statement. The backward jump is just to keep track of which top-level statement it has read so far. It's not about being positioned on what it's currently running. > painstakingly executing it in a way that doesn't require a buffer. I don't understand why people keep saying that. There's a buffer of 64 bytes. You mean in a way that doesn't require slurping the file. It avoids slurping precisely by buffering.
- DreadY2K 7y agoI tried running it in Vim (I have version 8.1.1401), with a regular bash script, and it didn't run the dangerous command. However, when I made a hard link to the same file, then it did run the dangerous command. My guess is that Vim defaults to writing a new file with the same name, but, if there is a hard-link pointing at the same file, then it has to actually modify the file in place. That is probably what bit you in the past (although I'm sure this behaviour is configurable somewhere). If you want to force bash to read the whole script into memory on startup, you can put the whole script inside a function, and then, on the last line of the file, call the function you just defined.
- firethief 7y ago> I guess I can understand why bash works this way.. it means that it can handle arbitrarily long scripts without having to read the entire script into memory at once. The normal way of reading a file (using a buffer) solves this. The only reason for doing this dance instead would be that it's considered part of the interface. I was going to look for it in the POSIX standard, but it looks like that would cost me $894.00, and that's $7 more than my entire verifying-comments-on-the-internet budget for this fortnight.