Closed phansch closed 4 years ago
Hi,
thank you for your feedback, for choosing/using the library, and for reporting the bug with full information needed.
I have tested your example on v0.0.5
(master
branch) as well on dev
branch, both with the same error message.
I suppose it fails because it tries to create a new tmux client within a std::process::Command?
Library is using std::process::Command::output()
function for executing all tmux subcommands
such as new-session
, attach-session
... I'm suspecting it has something to
do with pty
(not sure). I will check analogous libraries written in other languages.
Is there any way to make this work such that executing cargo run will attach to the tmux session directly?
Before I suggest some temporary workaround, please be advised, the library (especially dev
branch) is still in experimental development stage and it is not well tested:
So you use unstable versions on your own risk.
Current temporary workaround, which I can suggest:
The solution requires tmux_interface 0.0.6
from dev
branch:
git clone --branch dev https://github.com/AntonGepting/tmux-interface-rs.git
Create new test project:
cargo new issue1 --bin
Add dependencies using local path for the library and additional crate in issue1/Cargo.toml
...
[dependencies]
tmux_interface = { version = "0.0.6", path = "../tmux-interface" }
exec = "0.3.1"
TmuxInterface.pre_hook
structure field will be used for setting up a callback function, which will be executed before/instead of the actual std::process::Command::output()
. In the body of the callback function Exec::exec()
function is called, which in turn is a wrapper around execvp()
system call. Library documentation is still missing for this field because it is not completely implemented yet. At the moment you can look at sources src/tmux_interface.rs and the example below:
Example as issue1/src/main.rs
use tmux_interface::{AttachSession, NewSession, TmuxInterface};
fn main() {
let mut tmux = TmuxInterface::new();
let new_session = NewSession {
session_name: Some("foobar"),
detached: Some(true),
..Default::default()
};
tmux.new_session(Some(&new_session)).unwrap();
let attach = AttachSession {
target_session: Some("foobar"),
..Default::default()
};
// install the hook
tmux.pre_hook = Some(Box::new(|bin, options, subcmd| {
//println!("prehook: {:?} {:?} {:?}", bin, options, subcmd);
// something like this...
exec::Command::new(bin).args(subcmd).args(options).exec();
Ok(())
}));
tmux.attach_session(Some(&attach)).unwrap();
// remove the hook,
// so other functions calls of the same TmuxInterface instance will not be affected
tmux.pre_hook = None;
}
You can try it, then please give me some feedback if this behavior is something like what you was expecting. Thank you in advance.
This idea was introduced by Jezza. You can take a look at the Jezza's fork and a small project Jezza's txl-project using it.
If there is some better way (without any additional crates), I would appreciate any suggestions to make a nice straight forward solution.
After some research I think I've got the cause of the issue.
Accordingly to std::process::Command
documentation
doc.rust-lang.org:
By default, stdout and stderr are captured (and used to provide the resulting output). Stdin is not inherited from the parent and any attempt by the child process to read from the stdin stream will result in the stream immediately closing.
It seems like when tmux
is executed, it's trying to setup stdin
, after this
attempt the stream is immediately closed by std::process::Command::output()
, that causes
tmux
to exit with error open terminal failed: not a terminal
.
With the new commit (12e8c444f779dde184fc1c238f8beb3c7a2c0214) a small bug-fix was added. Soon after some tests and few preparations will be made, a new minor version of the library will be released.
Please check if it completely solves your problem and has no side effects for your purposes, in order to close this issue.
@AntonGepting Sorry for the late reply. Inheriting stdin seems to have fixed the problem, thanks!
Hi, thanks for this great library! I might be missing some information, but I'm having trouble attaching to an existing tmux session from outside tmux.
A simplified example:
Given an existing
foobar
session, doingcargo run
results in:I suppose it fails because it tries to create a new tmux client within a
std::process::Command
?I'm on linux, using
urxvt
as my terminal, attaching from my terminal directly, works of course. Is there any way to make this work such that executingcargo run
will attach to the tmux session directly?