Hi. I'm having trouble writing a wrapper script for the command line text editor gnu ed.
I want to be able to run the following algorithm on ed:
1. Display, on stdout, a command which I intend to feed into ed (before I actually feed it to ed).
2. Actually feed the command into ed's stdin.
3. Wait until ed finishes displaying whatever stderr and stdout it must, redirecting all (stderr and stdout) to stdout.
4. End if the command is q or Q.
5. Otherwise, go back to step 1.
I want to achieve this, in order to be able to automate ed (or any other command-line utility for that matter) through bash scripts, WHILE displaying all i/o interaction (this is important).
Anyway, my first try was to use the following shell script display_and_feed.sh :
as follows
the problem being, that I get this messy, disordered output (which consists of a mix of stderr and stdout, by the way):
...so I'm thinking, "maybe an ugly time delay will do...", so then I write a new script:
display_and_feed_with_delay.sh :
...I run:
And sure enough, the (SLOW) script, returns the orderly output:
So I unsuspectingly cheer and celebrate, but when I try to store it all neatly in a file, I get:
Apparently, stderr gets redirected to file before stdout does. I am puzzled. Why does this happen??
By the way, this also happens when I try to use a pipe instead of redirecting to a file:
Is this an exclusive ed behavior, or do all programs first pipe their stderr and then their stdout? Is there a way to merge (interwine, in the correct order) stderr and stdout, for ed, in a case like this?
I mean, this behavior is kinda funny, because, when I run stuff like
I get
Not
By the way: it would be awesome if there was a way to tell when ed is expecting new input, so that I can signal some script, which sends input into ed, when the moment is right, to feed ed more commands, instead of using some ugly sleep 0.5 time delay. Is there any way to do this?
There are a number of wrong presumptions in your post about how some Unix-facilities work. I will try to address them one by one. Bear with me, sometimes the relation of explanation and problem will not immediately become clear. It will (should) make sense in the end.
You have to picture a Unix process like a garden hose. You put something in on top and it comes out at the bottom. If you connect two such processes with a pipeline symbol you stick two of these garden hoses together, so that the outcome of one goes directly into the other.
Now the picture of the garden hose is simple, but yet a bit misleading: first off, because processes change the data stream they are working on: you put lots of blue water in on top and get a small amount of red water out on bottom (or vice versa). But the more important shortcoming of the picture is that the garden hose is Y-shaped: it has two outputs, STDOUT and STDERR (and even more outputs if you defined them, but these two are there per default).
Notice that there is a strict difference between the outlet of a garden hose and the place it is directed at. You can catch what comes out of the hose by either this bucket or the other (or, see above, even the intake of another garden hose), but there is still a difference between the destination a hoses ending is pointed at and the destination itself.
Coming back to your script from this rather theoretical explanation: a command like "2>&1" means: "direct what comes out of stderr (one hose ending) to where the stdout (the other hose ending) is already pointing at". This does in no way imply that these two streams are now somehow "merged". They are not. They are just pointing to the same bucket, but are still two different hose endpieces. If you first redirect stderr to point to the same bucket (file or pipeline) as stdout and then redirect stdout to point to another bucket stderr will not be affected in any way - two different streams.
Now for another misconception directly related to your last point with the redirected "echo"s: in fact it is in no way guaranteed to get any particular succession if different streams are involved. If you write:
you are guaranteed that "a" is displayed before "b". If you have "c" and then "d" coming out of stderr and you merge these two streams in one destination you are also guaranteed that "c" shows up before "d", but there is no such guarantee that "c" or "d" will show up in any particular position relatively to "a" or "b". it could be "a-b-c-d" or "c-d-a-b" or even "c-a-d-b" or "a-c-b-d" - all these variations would be valid ouputs for the following code:
The reason is that stderr and stdout are radically different even if they look just like two of the same kind: one of them is buffered, the other one unbuffered. That means that repeated calls to output something are stored and then handled in one big rush versus processing each request as soon as it comes.
Another thing you seem to miss is a rather small issue: "sleep" can only handle integers. "sleep 0.5" might work on some system if this system has extended the standard but will definitely fail on most. If you want to "sleep for less than a second" i suggest you search this board for the "nodoff" utility Perderabo has programmed once.
The reason is that stderr and stdout are radically different even if they look just like two of the same kind: one of them is buffered, the other one unbuffered. That means that repeated calls to output something are stored and then handled in one big rush versus processing each request as soon as it comes.
...inspired me to search for "make stdout unbuffered bash" in google, which led me to a stack overflow thread, which in turn referred me to the expect command, which pretty much solves my original problem.
Thanks for the buffering details of stdin and stdout, bakunin, I appreciate it.
Hi Gurus,
I need to build a wrapper script which will be passing the loading date and the data file name (provides option to the user to load a single data file or load all the data files) to the actual loader data_load.ksh to load in the database.
1. I want to execute the loader script... (6 Replies)
I am trying to build a sinkhole for BIND. I created a master zone file for malicious domains and created a separate conf file, but I am stuck.
I have a list of known bd domains that is updated nightly. The file simply contains the list of domains, one on each line:
Bad.com
Bad2.com... (4 Replies)
Hi friends,
i am working in ksh88. i am running the follwing wapper script in background to run two jobs parallely((eg nohup wrapper.ksh &)::
wrapper.ksh
########################
#!/bin/ksh
nohup ./pii_insert.ksh /nsing83/p2/test &
nohup ./pii_update.ksh... (1 Reply)
Hi,
I am writing a wrapper script(wrap_script.sh) to one of the main scripts (main_script.sh)
The main script is executed as following:
./main_script.sh <LIST> <STARTDATE> <ENDDATE>
looks for a parameter which is a LIST(consists of different list names that need to be processed), START/END... (0 Replies)
I have this a code that I got help with for another task. I since tried to modify it to work on this task.
I need someones expertise to modify it slightly and I am not sure where to start or yet fully understand the logic.
I am trying to get a script to read my m-names.txt which has lots... (19 Replies)
Hi,
I am in need of way to facilitate this senerio in a perl script.
I have CLI ( command line interface) which I run like so:
kip-tepltist -u Xxx -p Xxx
Which produces tones of names from each template it found:
194Iselin-NJ
33-IDFLB-North-611-Woodward-8600 ... (5 Replies)
Hello,
I have the below wrapper script:
#!/usr/bin/perl -w
if ($^O eq 'MSWin32' ) {
$subnet = 'c:\path\to\subnet.txt';
}
else {
$subnet = '/opt/qip/wrapper-del-sub';
}
open FH1, 'jj-deleted-subnets.txt' or die "Can't open 'jj-deleted-subnets.txt'
... (0 Replies)
Hi,
I knw its a silly question, but am a newbie to 'vi' editor. I'm forced to use this, hence kindly help me with this question.
How can i paste a chunk 'copied from' a different editor(gedit) in 'vi editor'?
As i see, p & P options does work only within 'vi'. (10 Replies)