From c41fc52077de071329a96ed8fce93cc9fca151e7 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Sat, 11 Oct 2025 12:23:36 +0200 Subject: [PATCH] bg: deduplicate job argument "bg %1" of a pipline prints the same line twice because it tries to background the same job twice. This doesn't make sense and other builtins like "disown" already deduplicate, so do the same. Unfortunately we can't use the same approach as "disown" because we can't hold on to references to job, since we're modifying the job list. --- src/builtins/bg.rs | 9 +++++++-- tests/checks/tmux-job.fish | 8 ++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/builtins/bg.rs b/src/builtins/bg.rs index 07dd80635..fb86c6198 100644 --- a/src/builtins/bg.rs +++ b/src/builtins/bg.rs @@ -1,5 +1,7 @@ // Implementation of the bg builtin. +use std::collections::HashSet; + use crate::proc::Pid; use super::prelude::*; @@ -97,9 +99,12 @@ pub fn bg(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> Built // Background all existing jobs that match the pids. // Non-existent jobs aren't an error, but information about them is useful. + let mut seen = HashSet::new(); for pid in pids { - if let Some((job_pos, _job)) = parser.job_get_with_index_from_pid(pid) { - send_to_bg(parser, streams, cmd, job_pos)?; + if let Some((job_pos, job)) = parser.job_get_with_index_from_pid(pid) { + if seen.insert(&*job as *const _) { + send_to_bg(parser, streams, cmd, job_pos)?; + } } else { streams .err diff --git a/tests/checks/tmux-job.fish b/tests/checks/tmux-job.fish index 25b9a72a6..6bb5384fc 100644 --- a/tests/checks/tmux-job.fish +++ b/tests/checks/tmux-job.fish @@ -17,3 +17,11 @@ isolated-tmux capture-pane -p # CHECK: fish: Job 1, 'sleep 0.5 &' has ended # (I've seen this print " world", I guess it depends on tmux version and how big it thinks the terminal is) # CHECK: {{.*}} world + +isolated-tmux send-keys C-u C-l "sleep 3 | cat &" Enter "bg %1" Enter +tmux-sleep +isolated-tmux capture-pane -p | string match -v '*has stopped*' +# CHECK: prompt 0> sleep 3 | cat & +# CHECK: prompt 0> bg %1 +# CHECK: Send job 1 'sleep 3 | cat &' to background +# CHECK: prompt 1>