{"componentChunkName":"component---src-templates-post-template-js","path":"/docker-tabo-compleate-en","result":{"data":{"markdownRemark":{"id":"bfe198a8-8662-58fb-a3d8-cc7258e06c03","html":"<blockquote>\n<p>This page has been machine-translated from the <a href=\"/docker-tabo-compleate\">original page</a>.</p>\n</blockquote>\n<p>This article explains how to fix a problem where Tab completion does not work for arguments when using <code class=\"language-text\">make</code> inside a Docker container.</p>\n<p>I do my hobby OS development in a Docker container, and I ran into a problem where <strong>Tab completion for Makefile arguments did not work inside a container I logged into with the <code class=\"language-text\">docker run</code> command</strong>.</p>\n<p>Normally, I wanted Makefile arguments such as <code class=\"language-text\">make build</code> to be completed with the Tab key as shown in the following image, but it did not work correctly in the shell inside the Docker container I connected to.</p>\n<p><img src=\"assets/2021_01_11_2954.assets/image-1.png\" alt=\"img\"></p>\n<h2 id=\"solution\" style=\"position:relative;\"><a href=\"#solution\" aria-label=\"solution permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Solution</h2>\n<p>If Makefile Tab completion does not work, install <strong>bash-completion</strong> with the following command, then load <code class=\"language-text\">/etc/bash_completion</code> with Bash’s <code class=\"language-text\">source</code> command.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">sudo</span> <span class=\"token function\">apt</span> <span class=\"token function\">install</span> bash-completion -y\n<span class=\"token builtin class-name\">source</span> /etc/bash_completion</code></pre></div>\n<p>After that, Tab completion became available.</p>\n<p>But what is <code class=\"language-text\">bash-completion</code> in the first place?\nAccording to the README, it seems to be <strong>a tool for enhancing Tab completion in the Bash shell</strong>.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">bash-completion is a collection of command line command completions for the Bash shell, a collection of helper functions to assist in creating new completions, and a set of facilities for loading and installing completions automatically.</code></pre></div>\n<p>With <code class=\"language-text\">bash-completion</code> installed, <strong>you can also complete option arguments for standard tools such as <code class=\"language-text\">systemctl</code>, not just Makefile arguments</strong>.\nIt is extremely convenient.</p>\n<p>By the way, after installing <code class=\"language-text\">bash-completion</code>, you can check whether it is enabled by running the following command and seeing whether it produces a large amount of output.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">complete -p</code></pre></div>\n<p>The following article was helpful for more details.</p>\n<p><a href=\"https://qiita.com/yamada-hakase/items/bf163f0924e4d925fefb\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Using bash-completion to hammer out long commands without looking at man pages or help - Qiita</a></p>\n<h2 id=\"bash-completion-does-not-become-active-in-a-docker-container\" style=\"position:relative;\"><a href=\"#bash-completion-does-not-become-active-in-a-docker-container\" aria-label=\"bash completion does not become active in a docker container permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code class=\"language-text\">bash-completion</code> does not become active in a Docker container</h2>\n<p>So, if you add a line to install <code class=\"language-text\">bash-completion</code> to the Dockerfile and then build the image, it seems like the problem of Tab completion not working should be resolved.</p>\n<p>Here I created an image using the following Dockerfile.</p>\n<div class=\"gatsby-highlight\" data-language=\"dockerfile\"><pre class=\"language-dockerfile\"><code class=\"language-dockerfile\"><span class=\"token comment\"># Dokcerfile</span>\n<span class=\"token instruction\"><span class=\"token keyword\">FROM</span> python:3.8</span>\n<span class=\"token instruction\"><span class=\"token keyword\">ENV</span> PYTHONUNBUFFERED 1</span>\n\n<span class=\"token instruction\"><span class=\"token keyword\">ENV</span> TZ=Asia/Tokyo</span>\n\n<span class=\"token instruction\"><span class=\"token keyword\">RUN</span> mkdir -p /homedir</span>\n<span class=\"token instruction\"><span class=\"token keyword\">ENV</span> HOME=/homedir</span>\n<span class=\"token instruction\"><span class=\"token keyword\">WORKDIR</span> <span class=\"token variable\">$HOME</span></span>\n\n<span class=\"token comment\"># If you henge shell to Bash</span>\n<span class=\"token comment\"># Shell &amp;#91;\"/bin/bash\", \"-c\"]</span>\n\n<span class=\"token instruction\"><span class=\"token keyword\">RUN</span> useradd ubuntu</span>\n<span class=\"token instruction\"><span class=\"token keyword\">RUN</span> dpkg --add-architecture i386</span>\n<span class=\"token instruction\"><span class=\"token keyword\">RUN</span> apt update &amp;&amp; apt upgrade -y</span>\n\n<span class=\"token comment\"># Utils</span>\n<span class=\"token instruction\"><span class=\"token keyword\">RUN</span> apt install vim unzip zip gdb ltrace strace bash-completion -y</span>\n\n<span class=\"token comment\"># Devtools</span>\n<span class=\"token instruction\"><span class=\"token keyword\">RUN</span> apt install mtools nasm build-essential g++ make -y</span>\n\n<span class=\"token comment\"># Qemu</span>\n<span class=\"token instruction\"><span class=\"token keyword\">RUN</span> apt install qemu qemu-system-x86 qemu-utils qemu-system-arm -y</span></code></pre></div>\n<p><strong>However, when I logged into the image I created with the following command, Tab completion did not work.</strong></p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">docker</span> run --rm -it -v mydir:/homedir mycontainer /bin/bash</code></pre></div>\n<p><strong>If I ran <code class=\"language-text\">source /etc/bash_completion</code> inside the logged-in container first, Tab completion worked normally after that, so <code class=\"language-text\">bash-completion</code> itself seemed to be installed correctly.</strong></p>\n<p>Also, under <code class=\"language-text\">/etc/profile.d</code>, <code class=\"language-text\">bash_completion.sh</code> was present as shown below.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">root@ab80c3738102:~<span class=\"token comment\"># cat /etc/profile.d/bash_completion.sh</span>\n\n<span class=\"token comment\"># Check for interactive bash and that we haven't already been sourced.</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">[</span> -n <span class=\"token string\">\"<span class=\"token variable\">${<span class=\"token environment constant\">BASH_VERSION</span>-}</span>\"</span> -a -n <span class=\"token string\">\"<span class=\"token variable\">${<span class=\"token environment constant\">PS1</span>-}</span>\"</span> -a -z <span class=\"token string\">\"<span class=\"token variable\">${BASH_COMPLETION_VERSINFO-}</span>\"</span> <span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span> <span class=\"token keyword\">then</span>\n\n    <span class=\"token comment\"># Check for recent enough version of bash.</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">[</span> <span class=\"token variable\">${<span class=\"token environment constant\">BASH_VERSINFO</span><span class=\"token punctuation\">[</span>0<span class=\"token punctuation\">]</span>}</span> -gt <span class=\"token number\">4</span> <span class=\"token punctuation\">]</span> <span class=\"token operator\">||</span> <span class=\"token punctuation\">\\</span>\n       <span class=\"token punctuation\">[</span> <span class=\"token variable\">${<span class=\"token environment constant\">BASH_VERSINFO</span><span class=\"token punctuation\">[</span>0<span class=\"token punctuation\">]</span>}</span> -eq <span class=\"token number\">4</span> -a <span class=\"token variable\">${<span class=\"token environment constant\">BASH_VERSINFO</span><span class=\"token punctuation\">[</span>1<span class=\"token punctuation\">]</span>}</span> -ge <span class=\"token number\">1</span> <span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span> <span class=\"token keyword\">then</span>\n        <span class=\"token punctuation\">[</span> -r <span class=\"token string\">\"<span class=\"token variable\">${XDG_CONFIG_HOME<span class=\"token operator\">:-</span>$HOME<span class=\"token operator\">/</span>.config}</span>/bash_completion\"</span> <span class=\"token punctuation\">]</span> <span class=\"token operator\">&amp;&amp;</span> <span class=\"token punctuation\">\\</span>\n            <span class=\"token builtin class-name\">.</span> <span class=\"token string\">\"<span class=\"token variable\">${XDG_CONFIG_HOME<span class=\"token operator\">:-</span>$HOME<span class=\"token operator\">/</span>.config}</span>/bash_completion\"</span>\n        <span class=\"token keyword\">if</span> <span class=\"token builtin class-name\">shopt</span> -q progcomp <span class=\"token operator\">&amp;&amp;</span> <span class=\"token punctuation\">[</span> -r /usr/share/bash-completion/bash_completion <span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span> <span class=\"token keyword\">then</span>\n            <span class=\"token comment\"># Source completion code.</span>\n            <span class=\"token builtin class-name\">.</span> /usr/share/bash-completion/bash_completion\n        <span class=\"token keyword\">fi</span>\n    <span class=\"token keyword\">fi</span>\n\n<span class=\"token keyword\">fi</span></code></pre></div>\n<p>Because of that, it seems that the cause was <strong><code class=\"language-text\">/etc/profile.d/bash_completion</code>, which should normally be loaded by <code class=\"language-text\">/etc/profile</code> when the shell starts, was not being loaded when I logged in with the method above</strong>.</p>\n<p>When I checked the documentation for the <code class=\"language-text\">docker run</code> command, I found the following description.</p>\n<blockquote>\n<p>The <code class=\"language-text\">docker run</code> command first creates a writable container layer on top of the specified image, then starts it using the specified command.</p>\n<p>In other words, <code class=\"language-text\">docker run</code> is equivalent to the API endpoints <code class=\"language-text\">/containers/create</code> and <code class=\"language-text\">/containers/(id)/start</code>.\nA stopped container can be restarted with all previous changes preserved by using <code class=\"language-text\">docker start</code>.</p>\n<p>See <code class=\"language-text\">docker ps -a</code> to list all containers.</p>\n<p><a href=\"https://docs.docker.com/engine/reference/commandline/run/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://docs.docker.com/engine/reference/commandline/run/</a></p>\n</blockquote>\n<p>In other words, <strong>calling <code class=\"language-text\">/bin/bash</code> with the <code class=\"language-text\">docker run -it</code> command means starting an interactive Bash process inside the launched Docker container and connecting the caller’s standard input and output to it through a pseudo-TTY</strong>.</p>\n<p>The cause of the problem here was that <code class=\"language-text\">bash_completion</code>, which should be loaded by <code class=\"language-text\">/etc/profile</code> when the Docker container starts (that is, when connecting to the Bash process launched by <code class=\"language-text\">docker run</code>), was not being loaded.</p>\n<p>And that makes sense, because <strong><code class=\"language-text\">/etc/profile</code> is only loaded when logging in to a shell.</strong>\nSo if you only start Bash with the <code class=\"language-text\">run</code> command, it will not be loaded in the first place.</p>\n<p>Once I had identified the cause, I changed the Docker container startup command as follows.</p>\n<p><code class=\"language-text\">docker run --rm -it -v mydir:/homedir mycontainer /bin/bash -login</code></p>\n<p>This <code class=\"language-text\">-login</code> option tells Bash to intentionally load environment settings such as <code class=\"language-text\">profile</code> before running.</p>\n<p>By connecting to a container started with this command, Tab completion started working properly.</p>\n<h2 id=\"summary\" style=\"position:relative;\"><a href=\"#summary\" aria-label=\"summary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Summary</h2>\n<p>I started writing this article as a quick memo, but it ended up deepening my understanding of Bash Tab completion, Docker commands, and how the Bash shell works, so it was very educational.</p>","fields":{"slug":"/docker-tabo-compleate-en","tagSlugs":["/tag/docker-en/","/tag/bash-en/","/tag/notes-en/","/tag/english/"]},"frontmatter":{"date":"2021-01-11","description":"This article explains how to fix a problem where Tab completion does not work for arguments when using make inside a Docker container.","tags":["Docker (en)","Bash (en)","Notes (en)","English"],"title":"Why Tab completion does not work in a container started with docker run -it ... /bin/bash and how to fix it","socialImage":{"publicURL":"/static/dc4d8b7f8795f3c3d3489d9957d155f2/no-image.png"}}}},"pageContext":{"slug":"/docker-tabo-compleate-en"}},"staticQueryHashes":["251939775","401334301","825871152"]}