0

I just rebooted one of my systems for the first time in several months, restarted tmux and my usual set of bash shells for tailing various log files, and noticed that running fg n (i.e. fg followed by the job number) in bash to bring a suspended job to the foreground now prints the following warning:

$ fg 2
-bash: fg: warning: 2: job specification requires leading `%'

i.e. it seems to be demanding that I can't just use fg n any more, as I have been doing for decades, now it wants fg %n.

It's not even true: fg n without the % symbol still works as expected, it just prints this warning message before doing what I tell it to.

And if it were true, it would kind of suck. It's two extra keystrokes, and goes against about 30 years of "muscle-memory".

Is there any way to disable this annoying message? Preferably without recompiling bash.

I know that other bourne-like shells don't support this and require the %, but I don't really care what other shells do, or what POSIX might have to say about it, and bash has supported it for as long as I can remember. It's a useful convenience feature.

And I understand why requiring the % makes sense for the kill and wait built-ins, because they need to distinguish between jobspecs and PIDs - but fg and bg DON'T need to do that (also, I use kill and wait very rarely, but use fg dozens of times per day and have done so for decades, especially when programming because I have several files open in vi and numerous man pages opened at relevant sections, suspending them with ^Z and using fg n to switch between them).

I upgraded bash from 5.2.37 to 5.3-1 back in September (but haven't needed to restart any shells since then), so I guess that's when it started:

# grep upgrade.bash:amd64 /var/log/dpkg.log.2
2025-09-10 01:29:13 upgrade bash:amd64 5.2.37-2+b5 5.3-1

There are mentions of "job", "jobspec", and "job specification" in https://cgit.git.savannah.gnu.org/cgit/bash.git/tree/CHANGES but none of them mention this change or why it was made.

I found the patch fragment where the change was made in https://cgit.git.savannah.gnu.org/cgit/bash.git/commit/?id=b8c60bc9ca365f8261fa97900b6fa939f6ebc303, which shows when it was made but fails to mention why, it's just wrapped in an if true:

@@ -721,8 +688,7 @@ get_job_by_name (name, flags)
 
 /* Return the job spec found in LIST. */
 int
-get_job_spec (list)
-     WORD_LIST *list;
+get_job_spec (WORD_LIST *list)
 {
   register char *word;
   int job, jflags;
@@ -737,6 +703,14 @@ get_job_spec (list)
 
   if (*word == '%')
     word++;
+  else
+#if 1
+    /* This could be builtin_error or sh_invalidjob() */
+    builtin_warning (_("%s: job specification requires leading `%%'"), word);
+#else
+    /* TAG:bash-5.4 10/23/2024 */
+    return (BAD_JOBSPEC);
+#endif
 
   if (DIGIT (*word) && all_digits (word))
     {

Searching for BAD_JOBSPEC also shows:

...
+                  10/23
+                  -----
[...]
+
+builtins/common.c
+   - get_job_spec: warn about deprecated notation if the job spec doesn't
+     have a leading `%'; code to return BAD_JOBSPEC tagged for bash-5.4
+   - sh_invalidjob: new convenience function to print error for invalid
+     job specifications
+
+builtins/jobs.def, builtins/ kill.def, builtins/ wait.def, builtins/fg_bg.def
+   - handle BAD_JOBSPEC return from get_job_spec; call sh_invalidjob.
+     Nothing returns that yet.

The change in the commit above is tagged for 5.4, so somebody has jumped the gun on this pointless change.

There's no mention of this change on either the help-bash or bugs-bash mailing list archives.

1 Answer 1

2

Nobody has jumped the gun, the old syntax still works. But you're getting a deprecation warning: from 5.4 on, you'll be getting a failure instead.

You can fix both the future versions with a function similar to the following one:

fg () {
   if [[ $1 =~ ^[0-9]+$ ]] ; then
       builtin fg "%$1"
   else
       builtin fg "$@"
   fi
}
3
  • I disagree with you about not jumping the gun, but the function is useful. I think I'll use that. +1 Commented Nov 23 at 16:48
  • Actually, not quite. the else clause breaks on fg without a jobspec (i.e. to bring the most recent job back to the fg). Works fine with builtin fg "$@" instead of "$1". unquoted $1 would work too. Commented Nov 23 at 16:57
  • @cas: Yes, modify it as you like. :-) Commented Nov 23 at 17:23

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.