diff --git a/README.md b/README.md index e689f955ac..a7832508b8 100644 --- a/README.md +++ b/README.md @@ -686,9 +686,14 @@ ## Post-Processing Options: path to the binary or its containing directory --exec CMD Execute a command on the file after - downloading and post-processing, similar to - find's -exec syntax. Example: --exec 'adb - push {} /sdcard/Music/ && rm {}' + downloading and post-processing. Similar + syntax to the output template can be used + to pass any field as arguments to the + command. An additional field "filepath" + that contains the final path of the + downloaded file is also available. If no + fields are passed, "%(filepath)s" is + appended to the end of the command --convert-subs FORMAT Convert the subtitles to another format (currently supported: srt|ass|vtt|lrc) (Alias: --convert-subtitles) diff --git a/yt_dlp/options.py b/yt_dlp/options.py index ace353042e..c4cb57e2fa 100644 --- a/yt_dlp/options.py +++ b/yt_dlp/options.py @@ -1195,7 +1195,11 @@ def _dict_from_multiple_values_options_callback( postproc.add_option( '--exec', metavar='CMD', dest='exec_cmd', - help='Execute a command on the file after downloading and post-processing, similar to find\'s -exec syntax. Example: --exec \'adb push {} /sdcard/Music/ && rm {}\'') + help=( + 'Execute a command on the file after downloading and post-processing. ' + 'Similar syntax to the output template can be used to pass any field as arguments to the command. ' + 'An additional field "filepath" that contains the final path of the downloaded file is also available. ' + 'If no fields are passed, "%(filepath)s" is appended to the end of the command')) postproc.add_option( '--convert-subs', '--convert-sub', '--convert-subtitles', metavar='FORMAT', dest='convertsubtitles', default=None, diff --git a/yt_dlp/postprocessor/execafterdownload.py b/yt_dlp/postprocessor/execafterdownload.py index 24dc64ef0b..95159cbc27 100644 --- a/yt_dlp/postprocessor/execafterdownload.py +++ b/yt_dlp/postprocessor/execafterdownload.py @@ -20,12 +20,13 @@ def __init__(self, downloader, exec_cmd): def pp_key(cls): return 'Exec' - def run(self, information): - cmd = self.exec_cmd - if '{}' not in cmd: - cmd += ' {}' - - cmd = cmd.replace('{}', compat_shlex_quote(information['filepath'])) + def run(self, info): + tmpl, info_copy = self._downloader.prepare_outtmpl(self.exec_cmd, info) + cmd = tmpl % info_copy + if cmd == self.exec_cmd: # No replacements were made + if '{}' not in self.exec_cmd: + self.exec_cmd += ' {}' + cmd = self.exec_cmd.replace('{}', compat_shlex_quote(info['filepath'])) self.to_screen('Executing command: %s' % cmd) retCode = subprocess.call(encodeArgument(cmd), shell=True) @@ -33,4 +34,4 @@ def run(self, information): raise PostProcessingError( 'Command returned error code %d' % retCode) - return [], information + return [], info