Introduction
Bash scripting is an essential skill for many system administrators and developers when working with Linux systems. In particular, the "source" command in Bash is commonly used to execute a script or a set of commands in the current shell, allowing the script to modify the environment of the parent shell. However, when working with Windows Subsystem for Linux version 2 (WSL2), the "source" command can fail silently, causing confusion and frustration for developers. In this article, we will explore this issue in detail and provide solutions to ensure that your scripts work as expected.
The Bash Source Command
The "source" command is used in Bash to execute a script in the current shell. It is often used to set environment variables or define functions that are required by subsequent commands or scripts. The syntax for the "source" command is:
source
Where "
The Problem with the Source Command in WSL2
When working in WSL2, the "source" command can fail silently, meaning that it does not produce any error messages or output. This behavior can be particularly confusing when attempting to debug scripts. The reason for this behavior is related to the way that WSL2 handles the current working directory.
Understanding WSL2's Handling of the Current Working Directory
WSL2 maps the Linux file system to a Windows file system using the 9P protocol. When executing a script using the "source" command in WSL2, WSL2 first resolves the path of the script to a Windows file system path using a virtual file system called the "drvfs." However, the current working directory is not resolved in the same way. Instead, WSL2 continues to use the Linux file system path for the current working directory.
This behavior can cause the "source" command to fail silently. For example, consider the following script:
#!/bin/bash
echo "Current working directory: $PWD"
cd ..
echo "After changing directory, current working directory: $PWD"
When executing this script using the "source" command in WSL2, the output would be:
Current working directory: /mnt/c/Users/user/myproject
Note that the output stops at this point and does not display the changed directory. This behavior is because the "cd" command has changed the current working directory to the parent directory, but WSL2 continues to use the original Linux file system path.
Solutions for the Source Command in WSL2
To avoid the issue of the "source" command failing silently in WSL2, there are several solutions that you can consider:
Solution 1: Use Absolute Paths
One solution is to use absolute paths for all files in your scripts. This ensures that WSL2 does not need to resolve the path using the "drvfs" and continues to use the Linux file system path. For example:
#!/bin/bash
echo "Current working directory: $PWD"
cd /mnt/c/Users/user/myproject/..
echo "After changing directory, current working directory: $PWD"
This example uses an absolute path to change the directory.
Solution 2: Use the WSL2 Interop Service
Another solution is to use the WSL2 interop service. The interop service provides a way for WSL2 to call Windows applications directly. You can use the "wsl" command to call a Windows command prompt and execute your script. For example:
$ wsl cmd.exe /c "source myscript.sh"
This example uses the "wsl" command to call the command prompt in Windows and then executes the script using the "source" command.
Solution 3: Use a Full Shell Script
A third solution is to create a full shell script and execute it directly. This avoids the need for the "source" command altogether. For example:
#!/bin/bash
echo "Current working directory: $PWD"
cd /mnt/c/Users/user/myproject/..
echo "After changing directory, current working directory: $PWD"
This example is a full shell script that can be executed directly using the "bash" command.
When working with the Bash "source" command in WSL2, it is important to be aware of how WSL2 handles the current working directory. Using absolute paths or the WSL2 interop service are both solutions to the issue of the "source" command failing silently. Additionally, creating a full shell script is another option that avoids the need for the "source" command altogether. By understanding the behavior of WSL2 and these solutions, you can ensure that your scripts work as expected in WSL2.
Summary and References
- WSL2 Maps Linux File System to Windows File System using 9P Protocol https://docs.microsoft.com/en-us/windows/wsl/wsl2-faq#how-does-wsl-2-work
- The "drvfs" Virtual File System used by WSL2 to Resolve Paths https://docs.microsoft.com/en-us/windows/wsl/wsl2-faq#what-is-drvfs
- Understanding the Bash "source" command https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html#index- source
- Using the WSL2 Interop Service https://docs.microsoft.com/en-us/windows/wsl/interop