From e81b3e06c547d9ba3a15a61d91261d0376355619 Mon Sep 17 00:00:00 2001 From: Fabian Homborg Date: Sat, 22 May 2021 17:21:35 +0200 Subject: [PATCH] docs: Add a section on subshells to fish-for-bash-users --- doc_src/fish_for_bash_users.rst | 44 +++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/doc_src/fish_for_bash_users.rst b/doc_src/fish_for_bash_users.rst index b0108e851..5f89d80a5 100644 --- a/doc_src/fish_for_bash_users.rst +++ b/doc_src/fish_for_bash_users.rst @@ -7,6 +7,8 @@ This is to give you a quick overview if you come from bash (or to a lesser exten Many things are similar - they both fundamentally expand commandlines to execute commands, have pipes, redirections, variables, globs, use command output in various ways. This document is there to quickly show you the differences. +.. _bash-command-substitutions: + Command substitutions --------------------- @@ -262,6 +264,48 @@ Fish's blocking constructs look a little different. They all start with a word, Fish does not have an ``until``. Use ``while not`` or ``while !``. +Subshells +--------- + +Bash has a feature called "subshells", where it will start another shell process for certain things. That shell will then be independent and e.g. any changes it makes to variables won't be visible in the main shell. + +This includes things like: + +.. code-block:: sh + + # A list of commands in `()` parentheses + (foo; bar) | baz + + # Both sides of a pipe + foo | while read -r bar; do + # This variable will not be visible outside of the while loop. + VAR=VAL + # This background process will not be, either + baz & + done + +``()`` subshells are often confused with ``{}`` grouping, which does *not* use a subshell. When you just need to group, you can use ``begin; end`` in fish:: + + (foo; bar) | baz + # when it should really have been: + { foo; bar } | baz + # becomes + begin; foo; bar; end | baz + +The pipe will simply be run in the same process, so ``while read`` loops can set variables outside:: + + foo | while read bar + set -g VAR VAL + baz & + end + + echo $VAR # will print VAL + jobs # will show "baz" + +Subshells are also frequently confused with :ref:`command substitutions `, which bash writes as ```command``` or ``$(command)`` and fish writes as ``(command)``. Bash also *uses* subshells to implement them. + +The isolation can usually be achieved by just scoping variables (with ``set -l``), but if you really do need to run your code in a new shell environment you can always use ``fish -c 'your code here'`` to do so explicitly. + Builtins and other commands ---------------------------