Bash 库德利贝特突然赢了';我不接受文件列表,除非我手动键入它

Bash 库德利贝特突然赢了';我不接受文件列表,除非我手动键入它,bash,fish,Bash,Fish,编辑:我不知道这个问题是否会得到解决,但它可能不再重要了。我也是,他们的反应是立即修复程序以允许转义逗号,并告诉我有关的(这就是为我修复它的原因) 因此,我正在运行一个命令,将文件列表自动排入quodlibet(一个音乐播放器)中:我已经在bash和fish中对其进行了测试 quodlibet --enqueue-files="\"$(tail -n +2 $HOME/Dropbox/Playlists/queue | sed ':a;N;$!ba;s|\n|","|g')\"" 鱼的版本是:

编辑:我不知道这个问题是否会得到解决,但它可能不再重要了。我也是,他们的反应是立即修复程序以允许转义逗号,并告诉我有关的(这就是为我修复它的原因)

因此,我正在运行一个命令,将文件列表自动排入quodlibet(一个音乐播放器)中:我已经在bash和fish中对其进行了测试

quodlibet --enqueue-files="\"$(tail -n +2 $HOME/Dropbox/Playlists/queue | sed ':a;N;$!ba;s|\n|","|g')\""
鱼的版本是:

quodlibet --enqueue-files=\"(tail -n +2 $HOME/Dropbox/Playlists/queue | sed ':a;N;$!ba;s|\n|","|g')\"
几个星期以来,我一直很高兴地使用这个精确的bash命令,它工作得非常好。然而,它突然停止了工作。这是最奇怪的部分。我有两台运行ArchLinux的计算机。有一个是我经常更新的,桌面,还有一个是我很久没有升级过的,笔记本电脑。它有quodlibet、bash和fish的稍旧版本。我只带着笔记本电脑离开了一段时间,并一直愉快地使用这个命令。但是,几天前,在我没有升级或更改任何关于quodlibet、bash、fish、命令甚至整个系统的内容的情况下,它突然停止了工作。现在,我回到家中,看到升级后的桌面,它也不工作了,好像整个问题都是基于系统时钟或其他原因

那么它到底是如何不起作用的呢?嗯,它完全不做任何事情,也不输出任何结果。如果它工作,它应该不会输出任何输出,但它不工作,而且似乎没有错误。但是,这里是它变得特别奇怪的地方。如果我把它分成两个命令,它实际上仍然可以正常工作。如果我跑

echo "\"$(tail -n +2 $HOME/Dropbox/Playlists/queue | sed ':a;N;$!ba;s|\n|","|g')\""
然后复制输出并将其粘贴到quodlibet--enqueue file=,就可以了

示例:假设文件$HOME/Dropbox/Playlists/queue中有3个音乐文件:

/home/jimi/Music/Song1.mp3
/home/jimi/Music/Song2.mp3
/home/jimi/Music/Song3.mp3
字符串“\”$(tail-n+2$HOME/Dropbox/Playlists/queue | sed):a;n;$!ba;s |\n |“,“|g')\”将其计算为

"/home/jimi/Music/Song2.mp3","/home/jimi/Music/Song3.mp3"
(由于使用了不同的命令,第一首歌开始播放,而不是排队。)如果我尝试将字符串“\”$(tail-n+2$HOME/Dropbox/Playlists/queue | sed):a;n;$!ba;s | \n |“,“| g')\”(直到几天前才起作用)排队,它就不起作用了。但是,如果我手动粘贴“/home/jimi/Music/Song2.mp3”、“/home/jimi/Music/Song3.mp3”,效果很好。我不知道这是为什么。我已经做了一系列的测试,试图找出答案,但都一无所获。我所做的两个重要的测试是在鱼身上尝试,以找到完全相同的行为,并尝试

quodlibet --enqueue-files=$(echo "\"$(tail -n +2 $HOME/Dropbox/Playlists/queue | sed ':a;N;$!ba;s|\n|","|g')\"")
因为它似乎非常喜欢echo的输出。但是,两者都不起作用。归根结底,quodlibet决定只接受我自己手动输入的文件,尽管由于bash的工作方式,它应该无法判断我是否自己输入了它

编辑:新消息:引用是问题的根源。如果我跑

quodlibet --enqueue-files="$(tail -n +2 $HOME/Dropbox/Playlists/queue | sed ':a;N;$!ba;s|\n|,|g')"
它起作用了。有什么区别?这个字符串避免了sed字符串中包含任何引号。我知道它特别是sed引号(sed):a;N;$!ba;s |\N |“,“| g”),因为我已经在没有其他引号的情况下对它进行了测试。不管怎么说,sed引用了一段话。当我移除这些时,它就起作用了。这不是一个可行的解决方案,因为为了让quodlibet不曲解任何文件名中有逗号的歌曲,我需要这些引号。我逃不过逗号,它不接受。所以,我试过这个:

\"$(tail -n +2 $HOME/Dropbox/Playlists/queue | sed ':a;N;$!ba;s|\n|\",\"|g')\"

但那也不行!看来quodlibet不会接受任何在sed行中有引号的东西!当我尝试使用转义单引号时,bash会给我一个换行符,就好像命令还没有完成键入一样。

我认为你没有做到这一点。我得承认我不认识鱼,但对Bash来说,你说的话没有什么意义

当您粘贴“…”时,外壳将从引号中剥离。证人:

vnix$ printf '>>%s<<\n' "/home/jimi/Music/Song2.mp3","/home/jimi/Music/Song3.mp3"
>>/home/jimi/Music/Song2.mp3,/home/jimi/Music/Song3.mp3<<
(由于
sed
可以很好地删除第一行,我冒昧地将
tail
分解出来。)请尝试对
printf
进行同样的操作,看看我们得到了什么:

vnix$ printf '>>%s<<\n' quodlibet --enqueue-files="$(sed -e 1d \
    -e ':a' -e 'N' -e '$!ba' -e 's|\n|","|g' -e 's/.*/"&"/' quodlibet)"
>>quodlibet<<
>>--enqueue-files="/home/jimi/Music/Song2.mp3","/home/jimi/Music/Song3.mp3"<<

vnix$printf'>%sUnless qud Libet明确且奇怪地要求在文件名列表中使用双引号,
\“
看起来大错特错。在shell脚本中看到引号的大多数地方,它们都是用于shell的,并由shell处理,例如,确保参数作为单个字符串传入。@tripleee这需要我来处理。否则,文件名中带有逗号的歌曲将被解释为两个单独的文件。转义逗号不起作用,所以我必须在每个文件周围加引号。我知道--enqueue files=的语法很糟糕。我同意。而且它与任何其他quodlibet命令的语法都不匹配。我不知道这是怎么回事。@tripleee,不过你的思路是对的。你刚刚帮我找到了线索。我会用它来编辑我的帖子。@Jimi James该命令的语法有点粗糙,是的(我写的),但这里有一些很好的背景说明:@NickB是的,我现在明白了。对不起,我的语言。当然,这些是获得我想要的输出的其他方法,但看起来quodlibet也不喜欢它们。它们也产生正确的输出,但在quodlibet中什么也不做。再一次,如果我删除sed行中的引号——也就是说,用逗号替换“,”,它会起作用(除非我有一首歌的名字中有逗号)。看起来quodlibet确实知道我是否手工输入了文件名,并且只接受双引号。
quodlibet --enqueue-files="$(sed '1d;:a;N;$!ba;s|\n|","|g;s/.*/"&"/' $HOME/Dropbox/Playlists/queue)"
vnix$ printf '>>%s<<\n' quodlibet --enqueue-files="$(sed -e 1d \
    -e ':a' -e 'N' -e '$!ba' -e 's|\n|","|g' -e 's/.*/"&"/' quodlibet)"
>>quodlibet<<
>>--enqueue-files="/home/jimi/Music/Song2.mp3","/home/jimi/Music/Song3.mp3"<<