Search code examples
bashshellzsh

How to prevent sourcing a part of a bash script?


I have a shell script with a syntax compatible to both bash and zsh, except for a section that has zsh specific syntax. that throws syntax errors if sourced from a bash is there an easy way to escape such section when using bash.


The script is a bash function that sources all the files in a directory. it works fine form zsh (and it is irrelevant to the question)

#!/usr/bin/env bash

shell=$(ps -p $$ -oargs=)

if [ $shell = "bash" ]; then
    for f in ~/.functions.d/*.sh; do source $f; done
elif [ $shell = "zsh" ]; then
    for f (~/.functions.d/**/*.sh) source $f
fi

the error is produced by the 7th line, when sourcing it in bash


relevant links


Solution

  • The problem is that the entire if/elif/else statement is parsed as a unit, so it can't contain invalid syntax.

    What you could do is exit the sourced script before executing the zsh-specific code:

    shell=$(ps -p $$ -oargs=)
    
    if [ $shell = "bash" ]; then
        for f in ~/.functions.d/*.sh; do source $f; done
        return
    fi
    
    if [ $shell = "zsh" ]; then
        for f (~/.functions.d/**/*.sh) source $f
    fi
    

    However, a more general solution is to extract the bash-specific and zsh-specific code into separate scripts.

    shell=$(ps -p $$ -oargs=)
    
    if [ $shell = "bash" ]; then
        source load_functions.bash
    fi
    
    if [ $shell = "zsh" ]; then
        source load_functions.zsh
    fi
    

    load_functions.bash would contain the first for loop, while load_functions.zsh would have the second one.