Setting Temporary Environment Variables for Single Commands in Fish Shell: A Practical Guide


3 views

In Fish shell, you can achieve the same effect as Bash's EDITOR=vim crontab -e using the env command or Fish's own syntax:

env EDITOR=vim crontab -e
# or using Fish's built-in syntax:
EDITOR=vim command crontab -e

Fish handles environment variables more strictly than Bash. The shell doesn't support Bash-style inline variable assignments before commands because:

  • Fish's parser treats the entire line as a single command
  • Variable assignments need to be explicit in Fish's syntax

Here are common use cases where temporary environment variables are useful:

# Running Python with custom environment
env PYTHONPATH=/custom/path python3 script.py

# Temporary HTTP proxy configuration
env http_proxy=http://proxy.example.com:8080 curl example.com

# Setting locale for a single command
env LANG=C.UTF-8 ls -l

For more complex scenarios, consider these alternatives:

# Using a sub-shell with temporary variables
begin; set -lx EDITOR vim; crontab -e; end

# Multiple variables
env VAR1=value1 VAR2=value2 command

Choose between env and Fish's command based on:

  • env is more portable across shells
  • Fish's command syntax is slightly more efficient
  • env can be used with shebang lines

When switching from Bash to Fish shell, many developers encounter this common scenario: you need to temporarily set an environment variable for just one command execution. In Bash, the syntax VAR=value command works perfectly, but Fish has a different approach.

Fish provides two primary methods to achieve this:

# Method 1: Using the env command
env EDITOR=vim crontab -e

# Method 2: Using the begin/end block
begin; set -lx EDITOR vim; crontab -e; end

1. The env command method: This is the most straightforward approach and mirrors the behavior in Bash. The env command creates a new environment with the specified variables and runs the command within that environment.

# Example with multiple variables
env API_KEY=12345 DEBUG=true npm run test

2. The begin/end block method: This is Fish's native way to handle scoped variables. The -l flag makes the variable local, and -x exports it to child processes.

# More complex example with multiple commands
begin
    set -lx PATH /custom/path $PATH
    set -lx LC_ALL en_US.UTF-8
    ./build-script.sh
end
  • Use env for simple one-off commands where Bash compatibility is important
  • Use begin/end blocks when you need to:
    • Set multiple temporary variables
    • Execute multiple commands with the same environment
    • Maintain clean Fish shell scripting style

For frequently used command patterns, you can create Fish functions:

function crontab_vim
    env EDITOR=vim crontab $argv
end

Or even create a more generic wrapper:

function with_env
    env $argv
end

# Usage:
with_env EDITOR=nano crontab -e
with_env NODE_ENV=test npm test
  • Don't use regular variable assignment (set VAR value) as it persists beyond the command
  • Remember that begin/end blocks can be nested when needed
  • Be aware of variable scope when combining with other Fish features

For simple cases, env is slightly faster as it's a single binary. However, the difference is negligible for most use cases. The begin/end approach becomes more efficient when setting multiple variables.