Docker:无效的引用格式。

252

我正在跟随这个使用Docker的教程。当我尝试运行Docker(在run.sh脚本中)时:

docker run \
    -p 8888:8888 
    -v `pwd`/../src:/src \
    -v `pwd`/../data:/data -w /src supervisely_anpr \
    --rm \
    -it \
    bash

我遇到了以下错误:

docker: invalid reference format.

我花了2个小时,但实在不明白出了什么问题。非常感谢任何想法。


请查看以下链接,看看是否对您有所帮助:https://dev59.com/HqPia4cB1Zd3GeqP2rQN#45281200 - Oleg
6
请尝试运行以下命令:docker run -p 8888:8888 -v "\pwd`/../src":/src -v "`pwd`/../data":/data -w /src --rm -it supervisely_anpr bash。此命令可以帮助您在Docker容器中启动supervisely_anpr镜像,并将本地目录../src映射到容器内的/src目录,同时也将本地目录../data映射到容器内的/data`目录。此命令还会进入容器并启动一个bash终端交互会话,以便您可以执行各种操作。 - Tarun Lalwani
5
就像@TarunLalwani和@Oleg所提到的,您需要将“--rm”和“-it”移动到“run”和图像名称之间。虽然这并不解释错误消息。您是否检查过图像名称字符是否具有任何特殊编码或大写字母?从代码片段中复制粘贴对我有效,而“docker run --rm foo! bash”会打印与您相同的错误。 - gesellix
4
考虑发布一个答案,这样下一个人就可以更容易地找到它。 - lloiacono
9
除非你真的想将字符串拆分成单词,否则始终使用双引号引用美元展开。 在这里,使用"$(pwd)"(现代形式的 "\pwd`")。 你的命令变成了 docker run -p 8888:8888 -v "$(pwd)"/../src:/src -v "$(pwd)"/../data:/data -w /src supervisely_anpr --rm -it bash`。 - Martin Jambon
我的问题是docker-compose.yml文件指向了http://的URL。我把http://去掉后,它就可以工作了。 - high_byte
28个回答

262

在Powershell中,应该使用${pwd}代替$(pwd)


33
这就是导致我撞头在墙上的原因(有时候我讨厌微软)。 - beerwin
1
docker run --rm -ti --name zalenium -p 4444:4444 -p 5555:5555 \ -e SAUCE_USERNAME -e SAUCE_ACCESS_KEY \ -v /tmp/videos:/home/seluser/videos \ -v /var/run/docker.sock:/var/run/docker.sock \ dosel/zalenium start --sauceLabsEnabled true 我的命令有什么问题?它也给出了相同的错误。 - paul
...而且仅仅使用$pwd是不起作用的,这是显而易见的。 - Timo
2
对于像@paul这样遇到完全正确的命令却出现问题的人,请参考此答案https://dev59.com/tFcO5IYBdhLWcg3whR7M#65690853。 - Mohd Abdul Mujib
2
为什么这个有效?当我在Powershell中运行这两个命令时,$(pwd)${pwd}似乎输出完全相同的内容。 - Josh
2
问题没有标记为 powershell,因此仅将 \pwd`更改为${pwd}是不够的,因为它基于` 的行继续符。不清楚您反对的 $(pwd) 表达式来自何处,因为问题中没有提到它。在 PowerShell 中,$(pwd) 确实可以工作(尽管 $pwd 更可取),只要您将其用于 "..." 中,这通常是明智的,例如 "$(pwd)/../src:/src"(但最好使用 "$pwd/../src:/src")。只是 $(pwd) 作为子表达式时,不能作为未引用的复合标记的开头 /cc @Josh - mklement0

72

我在复制粘贴命令时遇到了相同的问题。相反,当我手动输入整个命令时,它可以正常工作!

祝好运...


5
在我的情况下,问题是引号被转换为一些花哨的 UTF-8 字符,而 Docker 无法识别。 - Piotr Czapla
3
在我的例子中,与普通连字符不同的是,“en dash”,如果你从网页上复制黏贴指令,或者像我一样从一个旨在作为Docker速查表使用的PDF文件中复制指令时可能会发生这种情况。 - Cito
1
谢谢你,对我来说是n8n文档中的“\”字符被我删除了。 - Alexy
1
好的,问题解决了... - muammar
1
什么..?哈哈,很容易错过,不错! - Erick Boshoff
1
对我来说,这是因为我在反斜杠(\)后面有额外的空格,需要删除额外的空格,因为反斜杠期望紧接着它的是一个新行。 - Rosemary

70
在“run”后的第一个不是标志或标志参数的参数被解析为图像名称。当解析失败时,它会告诉您引用格式,也就是图像名称(但可能是图像ID、固定的图像或其他语法)无效。在您的命令中:

运行时,第一个非标志或标志所需参数的参数被认为是图像名称。如果解析失败,则说明参考格式,即图像名称(也可能是图像ID、固定图像或其他语法)无效。在您的命令中:

 docker run -p 8888:8888 -v `pwd`/../src:/src -v `pwd`/../data:/data -w /src supervisely_anpr --rm -it bash

图像名称“supervisely_anpr”有效,因此您需要在命令中早些查找。在这种情况下,错误很可能是由于pwd输出带有空格的路径所致。空格后面的内容不再是-v的参数,docker尝试将其解析为图像名称。修复方法是在您无法保证其不含空格或其他特殊字符时引用卷参数。

当您这样做时,您将遇到下一个错误,“可执行文件未找到”。图像名称后的所有内容都会被解析为容器内要运行的命令。在您的情况下,它将尝试运行命令--rm -it bash,这几乎肯定会失败,因为--rm在您的镜像中不存在二进制文件。您需要重新排序参数以解决该问题:

 docker run --rm -it -p 8888:8888 -v "`pwd`/../src:/src" -v "`pwd`/../data:/data" -w /src supervisely_anpr  bash

我在这里的幻灯片中提供了有关这两个错误和原因的更多细节:https://sudo-bmitch.github.io/presentations/dc2018/faq-stackoverflow-lightning.html#29


3
第30张幻灯片解决了我的问题。我在Cygwin中运行一个.sh文件,将 # !/bin/bash(注意#!之间的空格)更改为 #!/bin/bash,然后将“行结束序列”从CRLF更改为LF。这就是我所做的全部操作。感谢@BMitch分享这些幻灯片。 - blongho
1
“supervisely_anpr” 图像名称是有效的,解决了我在另一个上下文中遇到的相同问题。 我只是有一个无效的图像名称(它不存在,我必须首先使用另一个 sh 脚本构建它,但我忽略了这一点)。 在测试期间,我还从命令中删除了图像名称。 两件事中的一件导致了错误。 - questionto42

16

在我没有设置一个环境变量的情况下,我遇到了这个问题。

docker push ${repo}${image_name}:${tag}

repoimage_name已定义,但tag未定义。

这导致了docker push repo/image_name:

这会引发docker: invalid reference format.错误。


我曾经遇到过同样的问题,通过设置缺失的环境变量来解决了它。export tag=latest - PHZ.fi-Pharazon
我的 docker buildFROM ${ORG}/ci-common:${CI_COMMON_VERSION} as builder 处失败,并显示了以下错误。后来发现这是由于前面的 ARG CI_COMMON_VERION=2 中有一个简单的拼写错误(缺少一个 S),我从另一个脚本中复制了这个错误,而那个脚本中到处都是这个错误,所以一直能正常工作。 - CodeManX
我也遇到了这个错误,我不小心打成了"example.org:foo/bar:latest"而不是"example.org/foo/bar:latest"。 - Adam

12

我遇到了类似的问题。 我遇到的问题是$(pwd)中有一个空格,这会导致docker运行失败。

将目录名称改为不含空格的名称,如果这是问题的原因,则应该可以正常工作。


12

我在Linux上遇到了相同的问题,这是因为目录名包含了空格。我通过使用"$(pwd)/path/to/go"而不是$(pwd)/path/to/go来解决了这个问题。


当我尝试使用 "%cd%:/path/to/go" 时,这对我在Windows CMD上也起作用了。 - MK.

8

针对其他可能出现问题的读者:
如果您恰好将docker命令写在一个文件中,比如run.sh,请检查您的行分隔符。在Linux中,它应该是LR,否则您会得到相同的错误。


如果你在Windows上使用WSL,就可能会发生这种情况。如果你不够注意,就会出现混合的行尾符。例如,当你从上下文菜单创建一个新的文本文件时。 - FonzTech

8

我将整个命令放在一行中执行,因为它被提及为这样做。

$ docker run --name testproject-agent \
-e TP_API_KEY="REPLACE_WITH_YOUR_KEY" \
-e TP_AGENT_ALIAS="My First Agent" \
testproject/agent:latest

但它应该是一个多行命令,我逐行复制了命令,并在每行后按下 enter,咔嚓!它成功了。

有时从网页上复制内容时,new-line 字符会被省略,因此我建议手动添加新行。


7

在我的情况下,命令是这样的

 docker run -d --name kong-database \
  --network=kong-net \
  -p 5432:5432 \
  -e "POSTGRES_USER=kong" \
  -e "POSTGRES_DB=kong" \
  -e "POSTGRES_PASSWORD=kongpass" \
  postgres:9.6

我试图一次性复制包括斜杠(\)在内的所有内容,但是出现了以下错误。
docker: invalid reference format.

命令中的斜杠(\)表示下一行,因此如果您尝试在单行中运行完整命令,请删除斜杠(\),这对我有效。
谢谢 :)

我没有去掉反斜杠,但是你的答案让我了解了出了什么问题。因为反斜杠(\)需要新行,如果你有空格,它将不会被Docker识别。只需删除反斜杠(\)后面的额外空格,复制粘贴就可以工作了。 - Rosemary

5

我一开始使用的是非常通用的命令

docker build .

后来发现我需要指定标签名称,否则就没有可用的名称了

docker build . -t image_name

然后它就起作用了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接