Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

exec on windows needs double quotes around filename, not single quotes #5889

Closed
siavash119 opened this issue Jun 4, 2015 · 5 comments
Closed
Labels

Comments

@siavash119
Copy link

I was trying to auto open the file after dl using exec on Windows build (i.e. youtube-dl youtubelink --exec mpc-hc64.exe), but I kept getting syntax error on windows e.g. ([exec] Executing command: mpc-hc64.exe 'The Doors - Break on Through (To the Other Side)-cJQwnAhXnBk.mp4'
blah blah syntax error file not found)

I see shlex_quote def in compat.py adds single quotes around the string and escapes single quotes if it can't import. I just removed the import and replaced the definition to wrap with double quotes and escape the double quotes.

compat.py excerpt:
def shlex_quote(s):
if re.match(r"^[-_\w./]+$", s):
return s
else:
return '"' + s.replace('"', '"'"'"') + '"'

Maybe you can import quote from shlex to use double quotes on windows, but this changed definition works for me, and I can work with/open the files with exec on Windows now.

@jaimeMF
Copy link
Collaborator

jaimeMF commented Jun 4, 2015

shlex.quote is only available in python 3.3 and higher, we can't use it in 2.7. And it seems that it uses single quotes, so we need to use a special function for windows.

Just to be clear, is there any way to use single quotes in the windows shell?

@siavash119
Copy link
Author

you can use single quotes in windows powershell, but i'm pretty sure you need double quotes or no quotes with escaped spaces (escape with '^') for cmd. I tried running youtube-dl link --exec player.exe in powershell with still no luck though; i think it spawns a cmd process since I can open files with mpc-hc64.exe 'file name.mp4'.

And actually I don't get a syntax error; i get file not found in mpc-hc since it's looking for files 'firstwordofname and 2ndword and 3rdword and lastword.mp4' like i'm sending multiple arguments to the player to make a playlist.

Surrounding the path with double quotes in windows cmd and keeping it single quotes elsewhere i think is the simplest solution.

also I see i can use --restrict-filenames to make the filename have no spaces which has shlex_quote and exec not add single quotes so it works. Without needed to manipulate the filename I can also do (replace "link" with the url or have it as a command argument)

youtube-dl link
for /F "delims=" %%a in ('youtube-dl link --get-filename') do set filename=%%a
mpc-hc64.exe "%filename%"

to get the filename of the downloaded vid and play it myself.

@marnunez
Copy link

This is my ugly, ugly, ugly hack for adb usage

adbWin.bat

@echo off
set str=%*
set str=%str:'="%
%str%

and in in youtube-dl:

--exec "adbWin.bat adb push {} /storage/sdcard1/"

Note that it will replace every occurrance of a single quote by a double quote

@jcandresen
Copy link

Batch file fix works until you get a title with a single quote in it. Is there a way to force it just to change the first and the last, with a batch file until there is a more permanent way?

@midas02
Copy link
Contributor

midas02 commented Apr 1, 2017

I ran into the same issue. The problem here is that there are two cases: youtube-dl will only return a quoted string when the path+filename contains spaces. If not, it will return an unquoted string. So that makes it harder to find a simple solution without turning to complicated batch files.

I'm currently using a similar workaround to the one proposed by marnunez, but this one is restricted to a single line.
It's based on the following for loop:
for /f "delims='" %a in ("string") do echo %a
In this loop, the single quote character has been set as the delimiter. So the loop will read the value string between the first and the second occurrence of the single quote character. And that's again the downside, if there's a single quote in the middle of your string, you're toast. But the upside is that it will return the value of string without quotes, whether or not the string was quoted in the first place or not.

Using the above, you can add it to youtube-dl in a single line, where %a becomes the trimmed string instead of {}. But be careful as many quote signs need to be doubled because you're using quotes within quotes! So here's an example. This will just echo the filename:
youtube-dl.exe http://abc --exec "for /f ""delims='"" %a in (""{}"") do echo %a"

This one is more complicated. An ffmpeg conversion of the output of youtube-dl to mkv, followed by the deletion of the original file. Be careful to always put %a between double double quotes as the filename may contain spaces.
youtube-dl.exe http://abc --exec "for /f ""delims='"" %a in (""{}"") do ffmpeg -i ""%a"" -c copy ""%~dpna.mkv"" && del ""%a"" "

The last example uses another interesting feature of the for loop. The resulting variables can be used with the following syntax (referenced in "for /?"):
%~fI - expands %I to a fully qualified path name
%~dI - expands %I to a drive letter only
%~pI - expands %I to a path only
%~nI - expands %I to a file name only
%~xI - expands %I to a file extension only

So in the above example, I used %~dpna to strip the filename, including the path, of its extension, so I could add another extension to it.

The only major downside to the above method, is that it can't handle filenames with quotes. In that case, you could write a batch file, or an executable, that takes a string, and strips it of its leading and trailing quote, if present. If anyone has a way of doing that in a single line command, as I've shown above, I'd be interested to learn about it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants