1

I have a vimscript which needs to query a environment variable which gets set on terminal buffers. How can I do this? I tried looking through the help to see what term / job commands could be used to query but didn't see anything.

e.g.

for buffer in term_list()
    let variable = s:get_variable(buffer, "$SOMETHING")
endfor
  • 2
    Environment vars in the terminal window's shell? A parent process (Vim) can't see what's in a child processes' memory. It would require some explicit communication between the two processes (e.g. child saves envvar values to a file that Vim then reads) which is pretty unlikely to exist in Vim (though you could set such a thing up yourself). (Somewhat related discussion: vi.stackexchange.com/questions/22947/…) – B Layer Mar 29 at 4:03
  • Thanks for the link! I'll go the I/O route you suggested – ColinKennedy Mar 29 at 16:32
3

I linked a bunch of Bash stuff here. Sorry if that's off the mark but the points made are almost all *nix and shell flavor agnostic.

So you are looking to read an environment variable form a shell running in one of Vim's terminal buffers. Unfortunately, such variables are located in the shell process's memory and the internals of a process, including said memory, are locked down tight from access by other processes...for obvious security reasons. This holds true even for the process that created it (the "parent"). Yes, a child inherits a lot of things from the parent when it is created but that's a one way mechanism and there's no other inherent capability allowing the parent to see what's going on inside it while it's running1. Going the other way a child process can never affect any part of the parent's environment, which includes its variables, its current working directory, its open files, its resource limits, etc (BashFAQ 060)

The story doesn't end there, though. Obviously processes can communicate with each other. Typical mechanims for this are shared memory, sockets, and named pipes aka FIFOs.

Vim doesn't provide anything that's directly relevant but if you're determined then you can fairly easily set something up yourself in Vim and the child shell. The simplest approach would have to be to just have the child dump the data of interest into a temporary file and have Vim read it from there. If you're not dealing with production systems or anything serious like that you might want to go that route.

Or if you want to try something a little more complex you could look at FIFOs which are pretty accessible in shell scripts (thus the above link to some relevant info). Also, one of the things a child inherits is the parent's open file descriptors so that might be useful...in combination with FIFOs or otherwise.

1The parent does have some lifecycle control, can send signals to the child (hello kill) and can read its exit code upon termination...none of which help here. (Note that I'm ignoring various hacks and other risky behaviors as well as debuggers and the like to avoid a trip into the weeds.)


For a bit more discussion around Vim, shells, parent-child relationships and inheritance see Why does !cd not change the directory. For a deep dive beyond Vim, check out Bash Process Management...chock full of juicy details.

| improve this answer | |
  • Thanks for all of the resources. This issue has been hard to search for "vim terminal jobs doesn't exactly have good SEO" so this has been super helpful. Thanks again! – ColinKennedy Mar 31 at 6:08
  • Sure. Happy to help. – B Layer Mar 31 at 9:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.