如何在嵌套在sed命令中的echo命令中转义$

问题描述 投票:0回答:2

我在makefile中有一个准备存储库的配方,它将所有.sh文件转换为可执行文件。

在Ubuntu 18.04中,以下makefile

SHELL:=/bin/bash

prepare_repo:
    pip install flake8==3.6.0
    rm -f .git/hooks/pre-commit
    flake8 --install-hook git
    git config --bool flake8.strict true

    sed  '/__main__/r'<(\
        echo -e "    import subprocess\n\
    subprocess.check_call(\"find . -name '*.sh'         \n\
       -exec sh -c '                                    \n\
         for f do                                       \n\
           git check-ignore -q  '$f'||                  \n\
           printf '%s\\\n'      '$f'                    \n\
         done                                           \n\
       ' find-sh {} + | xargs git update-index --chmod=+x\", shell=True)"\
    ) -i --  .git/hooks/pre-commit

我迷上了pre-commit事件,因为我想将不在.gitignore文件中的所有.sh文件都转换为可执行文件。

但是问题是,如果我进入.git/hooks/pre-commit,我将找到以下代码

#!/home/fadi/anaconda3/bin/python
import sys

from flake8.main import git

if __name__ == '__main__':
    import subprocess
    subprocess.check_call("find . -name '*.sh'          
       -exec sh -c '                                    
         for f do                                       
           git check-ignore -q  ''||                    
           printf '%s\n'        ''                  
         done                                           
       ' find-sh {} + | xargs git update-index --chmod=+x", shell=True)
    sys.exit(
        git.hook(
            strict=git.config_for('strict'),
            lazy=git.config_for('lazy'),
        )
    )

请注意此代码块$的转义方式。

git check-ignore -q  ''||                    
printf '%s\n'        ''                 
shell sed escaping echo
2个回答
0
投票

您用make中的美元逃脱了美元。

all:
    echo $$

prepare_repo:
    ...
    ...
       git check-ignore -q  '$$f'||                  \n\
       printf '%s\\\n'      '$$f'                    \n\
    ...

0
投票

这可能对您有用(GNU sed和shell):

cat <<EOF | sed -i -- '/__main__/r /dev/stdin'  .git/hooks/pre-commit        
import subprocess\n\
    subprocess.check_call(\"find . -name '*.sh'         
        -exec sh -c '                                    
         for f do                                       
           git check-ignore -q  '$f'||                  
           printf '%s\\\n'      '$f'                    
         done                                           
       ' find-sh {} + | xargs git update-index --chmod=+x\", shell=True)"
EOF

使用猫和管子而不是<(...)

N.B。 "的报价可能需要调整。

© www.soinside.com 2019 - 2024. All rights reserved.