New argument parsing fails with space-containing args #378

Closed
opened 2026-02-06 19:38:33 +03:00 by OVERLORD · 9 comments
Owner

Originally created by @joshuaboniface on GitHub (Feb 3, 2019).

I'm not sure exactly why, but when trying to use arguments in variables with spaces (#749), this fails:

JELLYFIN_RESTART_OPT="--restartpath /usr/lib/jellyfin/restart.sh"
Feb 03 03:45:51 jf1 jellyfin[26969]: Jellyfin.Server 10.1.0.0
Feb 03 03:45:51 jf1 jellyfin[26969]: Copyright ©  2019 Jellyfin Contributors. Code released under the GNU General Public License Version 2
Feb 03 03:45:51 jf1 jellyfin[26969]: ERROR(S):
Feb 03 03:45:51 jf1 jellyfin[26969]:   Option 'restartpath /usr/lib/jellyfin/restart.sh' is unknown.

Similar situation with the optional ffmpeg arguments:

JELLYFIN_FFMPEG_OPTS="--ffmpeg /usr/bin/ffmpeg --ffprobe /usr/bin/ffprobe"
Feb 03 03:47:13 jf1 jellyfin[27153]: Jellyfin.Server 10.1.0.0
Feb 03 03:47:13 jf1 jellyfin[27153]: Copyright ©  2019 Jellyfin Contributors. Code released under the GNU General Public License Version 2
Feb 03 03:47:13 jf1 jellyfin[27153]: ERROR(S):
Feb 03 03:47:13 jf1 jellyfin[27153]:   Option 'ffmpeg /usr/bin/ffmpeg --ffprobe /usr/bin/ffprobe' is unknown.

However, adding an = causes it to work:

JELLYFIN_RESTART_OPT="--restartpath=/usr/lib/jellyfin/restart.sh"
Feb 03 03:48:09 jf1 jellyfin[27317]: [03:48:09] [INF] Jellyfin version: 10.1.0.0
Feb 03 03:48:09 jf1 jellyfin[27317]: [03:48:09] [INF] Arguments: ["/usr/lib/jellyfin/bin/jellyfin.dll", "--datadir", "/var/lib/jellyfin", "--configdir", "/etc/jellyfin", "--logdir", "/var/log/jellyfin", "--cachedir", "/var/
cache/jellyfin", "--restartpath=/usr/lib/jellyfin/restart.sh", ""]

Given that the other (--*dir) options don't seem to require an =, something is fishy here. Will track testing to see if this is a systemd oddity, or an argument parsing oddity.

cc @ploughpuff @Bond-009

Originally created by @joshuaboniface on GitHub (Feb 3, 2019). I'm not sure exactly why, but when trying to use arguments in variables with spaces (#749), this fails: ``` JELLYFIN_RESTART_OPT="--restartpath /usr/lib/jellyfin/restart.sh" ``` ``` Feb 03 03:45:51 jf1 jellyfin[26969]: Jellyfin.Server 10.1.0.0 Feb 03 03:45:51 jf1 jellyfin[26969]: Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License Version 2 Feb 03 03:45:51 jf1 jellyfin[26969]: ERROR(S): Feb 03 03:45:51 jf1 jellyfin[26969]: Option 'restartpath /usr/lib/jellyfin/restart.sh' is unknown. ``` Similar situation with the optional `ffmpeg` arguments: ``` JELLYFIN_FFMPEG_OPTS="--ffmpeg /usr/bin/ffmpeg --ffprobe /usr/bin/ffprobe" ``` ``` Feb 03 03:47:13 jf1 jellyfin[27153]: Jellyfin.Server 10.1.0.0 Feb 03 03:47:13 jf1 jellyfin[27153]: Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License Version 2 Feb 03 03:47:13 jf1 jellyfin[27153]: ERROR(S): Feb 03 03:47:13 jf1 jellyfin[27153]: Option 'ffmpeg /usr/bin/ffmpeg --ffprobe /usr/bin/ffprobe' is unknown. ``` However, adding an `=` causes it to work: ``` JELLYFIN_RESTART_OPT="--restartpath=/usr/lib/jellyfin/restart.sh" ``` ``` Feb 03 03:48:09 jf1 jellyfin[27317]: [03:48:09] [INF] Jellyfin version: 10.1.0.0 Feb 03 03:48:09 jf1 jellyfin[27317]: [03:48:09] [INF] Arguments: ["/usr/lib/jellyfin/bin/jellyfin.dll", "--datadir", "/var/lib/jellyfin", "--configdir", "/etc/jellyfin", "--logdir", "/var/log/jellyfin", "--cachedir", "/var/ cache/jellyfin", "--restartpath=/usr/lib/jellyfin/restart.sh", ""] ``` Given that the other (`--*dir`) options don't seem to require an `=`, something is fishy here. Will track testing to see if this is a systemd oddity, or an argument parsing oddity. cc @ploughpuff @Bond-009
OVERLORD added the bugregression labels 2026-02-06 19:38:33 +03:00
Author
Owner

@JustAMan commented on GitHub (Feb 3, 2019):

I think it is the issue with scripts that start jellyfin. They're probably using problematic args like "$ENVVAR" (extra quoting).

@JustAMan commented on GitHub (Feb 3, 2019): I think it is the issue with scripts that start jellyfin. They're probably using problematic args like `"$ENVVAR"` (extra quoting).
Author
Owner

@ploughpuff commented on GitHub (Feb 3, 2019):

I can reproduce this on the command line as follows:

jellyfin "--restartpath /blah/blah/restart.sh"

ERROR(S):
  Option 'restartpath /blah/blah/restart.sh' is unknown.

Can you try removing the double quotes from JELLYFIN_RESTART_OPT:

JELLYFIN_RESTART_OPT=--restartpath /usr/lib/jellyfin/restart.sh

or

JELLYFIN_RESTART_OPT=--restartpath "/usr/lib/jellyfin/restart.sh"

@ploughpuff commented on GitHub (Feb 3, 2019): I can reproduce this on the command line as follows: ``` jellyfin "--restartpath /blah/blah/restart.sh" ERROR(S): Option 'restartpath /blah/blah/restart.sh' is unknown. ``` Can you try removing the double quotes from JELLYFIN_RESTART_OPT: `JELLYFIN_RESTART_OPT=--restartpath /usr/lib/jellyfin/restart.sh` or `JELLYFIN_RESTART_OPT=--restartpath "/usr/lib/jellyfin/restart.sh"`
Author
Owner

@joshuaboniface commented on GitHub (Feb 3, 2019):

That's not going to work, these are BASH variables with spaces (since its a flag and value) so removing the quotes will throw syntax errors. I could work around that for the restart one, but not the ffmpeg ones since there's two there.

@joshuaboniface commented on GitHub (Feb 3, 2019): That's not going to work, these are BASH variables with spaces (since its a flag and value) so removing the quotes will throw syntax errors. I could work around that for the restart one, but not the ffmpeg ones since there's two there.
Author
Owner

@ploughpuff commented on GitHub (Feb 3, 2019):

Before the invocation can you echo out the $JELLYFIN_ARGS string. I suspect there are some double-quotes in there (somehow not removed in bash var expansion?).

Also this local hack would help. In Jellyfin.Server/Programs.cs, print out the args strings:

public static async Task Main(string[] args)
{
    foreach (string s in args)
    {
        Console.WriteLine(s);
    }
    <snip>

I would expect to see something like:
--datadir
/var/lib/jellyfin
--configdir
/etc/jellyfin
--restartpath ~/blah/blah/restart.sh <-- Note how on one line..

@ploughpuff commented on GitHub (Feb 3, 2019): Before the invocation can you echo out the $JELLYFIN_ARGS string. I suspect there are some double-quotes in there (somehow not removed in bash var expansion?). Also this local hack would help. In Jellyfin.Server/Programs.cs, print out the args strings: ``` public static async Task Main(string[] args) { foreach (string s in args) { Console.WriteLine(s); } <snip> ``` I would expect to see something like: --datadir /var/lib/jellyfin --configdir /etc/jellyfin --restartpath ~/blah/blah/restart.sh <-- Note how on one line..
Author
Owner

@joshuaboniface commented on GitHub (Feb 3, 2019):

So just some more data points before I try recompiling something:

It looks like this setup "works" in the sense that it doesn't error out:

# Restart script for in-app server control
JELLYFIN_RESTART_OPT="--restartpath=/usr/lib/jellyfin/restart.sh"
# [OPTIONAL] ffmpeg binary paths
JELLYFIN_FFMPEG_OPTS="--ffmpeg=/usr/bin/ffmpeg --ffprobe=/usr/bin/ffprobe"

Which creates this systemd CLI:

   CGroup: /system.slice/jellyfin.service
           └─29839 /usr/bin/jellyfin --datadir=/var/lib/jellyfin --configdir=/etc/jellyfin --logdir=/var/log/jellyfin --cachedir=/var/cache/jellyfin --restartpath=/usr/lib/jellyfin/restart.sh --ffmpeg=/usr/bin/ffmpeg --ffprobe=/usr/bin/ffprobe

And these are the printed arguments:

Feb 03 12:39:38 jf1 jellyfin[29839]: [12:39:38] [INF] Jellyfin version: 10.1.0.0
Feb 03 12:39:38 jf1 jellyfin[29839]: [12:39:38] [INF] Arguments: ["/usr/lib/jellyfin/bin/jellyfin.dll", "--datadir=/var/lib/jellyfin", "--configdir=/etc/jellyfin", "--logdir=/var/log/jellyfin", "--cachedir=/var/cache/jellyfin", "--restartpath=/usr/lib/jellyfin/restart.sh", "--ffmpeg=/usr/bin/ffmpeg --ffprobe=/usr/bin/ffprobe", ""]     

But ultimately this doesn't work, and the ffmpeg arguments are ignored. This is the case even if I only set one of them, e.g.

jellyfin[32053]: [12:51:00] [INF] Arguments: ["/usr/lib/jellyfin/bin/jellyfin.dll", "--datadir=/var/lib/jellyfin", "--configdir=/etc/jellyfin", "--logdir=/var/log/jellyfin", "--cachedir=/var/cache/jellyf
in", "--restartpath=/usr/lib/jellyfin/restart.sh", "--ffmpeg=/srv/ffmpeg-4.0.3-64bit-static/ffmpeg", ""]
[...]
jellyfin[32053]: [12:51:02] [INF] FFMpeg: /usr/bin/ffmpeg
@joshuaboniface commented on GitHub (Feb 3, 2019): So just some more data points before I try recompiling something: It looks like this setup "works" in the sense that it doesn't error out: ``` # Restart script for in-app server control JELLYFIN_RESTART_OPT="--restartpath=/usr/lib/jellyfin/restart.sh" # [OPTIONAL] ffmpeg binary paths JELLYFIN_FFMPEG_OPTS="--ffmpeg=/usr/bin/ffmpeg --ffprobe=/usr/bin/ffprobe" ``` Which creates this `systemd` CLI: ``` CGroup: /system.slice/jellyfin.service └─29839 /usr/bin/jellyfin --datadir=/var/lib/jellyfin --configdir=/etc/jellyfin --logdir=/var/log/jellyfin --cachedir=/var/cache/jellyfin --restartpath=/usr/lib/jellyfin/restart.sh --ffmpeg=/usr/bin/ffmpeg --ffprobe=/usr/bin/ffprobe ``` And these are the printed arguments: ``` Feb 03 12:39:38 jf1 jellyfin[29839]: [12:39:38] [INF] Jellyfin version: 10.1.0.0 Feb 03 12:39:38 jf1 jellyfin[29839]: [12:39:38] [INF] Arguments: ["/usr/lib/jellyfin/bin/jellyfin.dll", "--datadir=/var/lib/jellyfin", "--configdir=/etc/jellyfin", "--logdir=/var/log/jellyfin", "--cachedir=/var/cache/jellyfin", "--restartpath=/usr/lib/jellyfin/restart.sh", "--ffmpeg=/usr/bin/ffmpeg --ffprobe=/usr/bin/ffprobe", ""] ``` But ultimately this doesn't work, and the ffmpeg arguments are ignored. This is the case even if I only set one of them, e.g. ``` jellyfin[32053]: [12:51:00] [INF] Arguments: ["/usr/lib/jellyfin/bin/jellyfin.dll", "--datadir=/var/lib/jellyfin", "--configdir=/etc/jellyfin", "--logdir=/var/log/jellyfin", "--cachedir=/var/cache/jellyf in", "--restartpath=/usr/lib/jellyfin/restart.sh", "--ffmpeg=/srv/ffmpeg-4.0.3-64bit-static/ffmpeg", ""] [...] jellyfin[32053]: [12:51:02] [INF] FFMpeg: /usr/bin/ffmpeg ```
Author
Owner

@ploughpuff commented on GitHub (Feb 3, 2019):

Ultimately it doesn't work because the parser cannot handle one long string, like this:
"--ffmpeg=/usr/bin/ffmpeg --ffprobe=/usr/bin/ffprobe"

Worth noting, from your final point, the --ffmpeg and --ffprobe switches must be given together or they are ignored. In that case I think the s/w searches AppPath and PATH for an installed version to use..

@ploughpuff commented on GitHub (Feb 3, 2019): Ultimately it doesn't work because the parser cannot handle one long string, like this: "--ffmpeg=/usr/bin/ffmpeg --ffprobe=/usr/bin/ffprobe" Worth noting, from your final point, the --ffmpeg and --ffprobe switches must be given together or they are ignored. In that case *I think* the s/w searches AppPath and PATH for an installed version to use..
Author
Owner

@ploughpuff commented on GitHub (Feb 3, 2019):

Parser is happy with:
--ffmpeg path
--ffmpeg "path"
"--ffmpeg=path"
"--ffmpeg=path" "--ffprobe=path"

Parser not happy with:
"--ffmpeg path" (Error: Option 'ffmpeg path' is unknown.)

Parses ok, but gives wrong expected result:
"--ffmpeg=path --ffprobe=path" (s/w has ffmpeg path set to "path --ffprobe=path", and ffprobe is null)

image

@ploughpuff commented on GitHub (Feb 3, 2019): Parser is happy with: --ffmpeg path --ffmpeg "path" "--ffmpeg=path" "--ffmpeg=path" "--ffprobe=path" Parser not happy with: "--ffmpeg path" (Error: Option 'ffmpeg path' is unknown.) Parses ok, but gives wrong expected result: "--ffmpeg=path --ffprobe=path" (s/w has ffmpeg path set to "path --ffprobe=path", and ffprobe is null) ![image](https://user-images.githubusercontent.com/33969763/52181743-5fd46c00-27ed-11e9-809f-9f205d9554bb.png)
Author
Owner

@JustAMan commented on GitHub (Feb 3, 2019):

@joshuaboniface what I suggest should work, export statement in bash behaves differently about spaces iirc, and that difference is probably the root cause here.

@JustAMan commented on GitHub (Feb 3, 2019): @joshuaboniface what I suggest should work, `export` statement in bash behaves differently about spaces iirc, and that difference is probably the root cause here.
Author
Owner

@joshuaboniface commented on GitHub (Feb 4, 2019):

"--ffmpeg=path" "--ffprobe=path"

This one doesn't work in bash/systemd units, the intervening space is ignored.

"--ffmpeg=path --ffprobe=path" (s/w has ffmpeg path set to "path --ffprobe=path", and ffprobe is null)

In my case, it defaults to what's set in the UI rather than overriding this.

I'll just specify every option explicitly in the environment with its own variable. It's a bit gross and I'd prefer the software to handle this better, but it's not a deal-breaker.

Edit: There were only two more that should ever really be used, so it wasn't too bad with this method. PR open.

@joshuaboniface commented on GitHub (Feb 4, 2019): > "--ffmpeg=path" "--ffprobe=path" This one doesn't work in bash/systemd units, the intervening space is ignored. > "--ffmpeg=path --ffprobe=path" (s/w has ffmpeg path set to "path --ffprobe=path", and ffprobe is null) In my case, it defaults to what's set in the UI rather than overriding this. I'll just specify every option explicitly in the environment with its own variable. It's a bit gross and I'd prefer the software to handle this better, but it's not a deal-breaker. Edit: There were only two more that should ever really be used, so it wasn't too bad with this method. PR open.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/jellyfin#378