英文:
How to embed Python code in a fish script?
问题
set PYCODE (cat << EOF
#INSERT_PYTHON_CODE_HERE
EOF
)
set RESPONSE (COLUMNS=999 /usr/bin/env python3 -c "$PYCODE" $argv)
set PYCODE "
#INSERT_PYTHON_CODE_HERE
"
set RESPONSE (COLUMNS=999 /usr/bin/env python3 -c "$PYCODE" $argv)
set FISH_SCRIPT (sed -e "/#INSERT_PYTHON_CODE_HERE/r $BASE_DIR/test_sh.py" $BASE_DIR/../src/mfa.fish)
英文:
I'm trying to convert over a Bash script that includes the following commands:
PYCODE=$(cat << EOF
#INSERT_PYTHON_CODE_HERE
EOF
)
RESPONSE=$(COLUMNS=999 /usr/bin/env python3 -c "$PYCODE" $@)
The idea being that a sed
find/replace is then used to inject an arbitrary Python script where #INSERT_PYTHON_CODE_HERE
is, creating the script that is then ran.
The corresponding Fish command would seem to be something like this
set PYCODE "
#INSERT_PYTHON_CODE_HERE
"
set RESPONSE (COLUMNS=999 /usr/bin/env python3 -c "$PYCODE" $argv)
but this falls apart when you have a Python script that can include both '
and "
(and any other valid) characters.
What is the correct way to handle translate this use of EOF
?
As a side note, I would prefer not to modify the sed
command that is injecting the python code, but for reference here it is:
set FISH_SCRIPT (sed -e "/#INSERT_PYTHON_CODE_HERE/r $BASE_DIR/test_sh.py" $BASE_DIR/../src/mfa.fish)
答案1
得分: 1
> PYCODE=$(cat << EOF
> #INSERT_PYTHON_CODE_HERE
> EOF
> )
这种表示字符串的方式叫做heredoc。Fish不支持heredocs,[详细的替代方案在这里](https://fishshell.com/docs/current/fish_for_bash_users.html#heredocs)。
> 相应的Fish命令似乎是这样的
>
> set PYCODE "
> #INSERT_PYTHON_CODE_HERE "
>
> 但是当你的Python脚本中同时包含单引号和双引号时,这种方式就不奏效了
不,它不会 - 你只需要使用反斜杠来转义引号,就像这样:
# 使用单引号
set -l py ''
import os
print("There\'s no place like:")
print(os.getenv('HOME'))
''
python3 -c $py
# 使用双引号
set -l py "
import os
print(\"There's no place like:\")
print(os.getenv('HOME'))
"
python3 -c $py
如果你有一个足够长的脚本,需要转义引号的话,考虑将脚本保存到一个文件中。毕竟,shell非常擅长处理文件。
如果你绝对希望在Fish中有类似HEREDOC的东西,你可以选择一些唯一的注释前缀,比如'###>',在你的Python脚本前面加上它,然后像这样将其读入一个变量:
# 模拟heredoc
###> import os
###> print("There's no place like:")
###> print(os.getenv('HOME'))
set -l py (grep "^###>" (status -f) | cut -c 6- | string collect)
python3 -c $py
英文:
> PYCODE=$(cat << EOF
> #INSERT_PYTHON_CODE_HERE
> EOF
> )
This style of representing a string is called a heredoc. Fish does not support heredocs, and details alternatives here.
> The corresponding Fish command would seem to be something like this
>
> set PYCODE "
> #INSERT_PYTHON_CODE_HERE "
>
> but this falls apart when you have a Python script that can include both ' and "
No it doesn't - you just need to escape quotes with a backslash like so:
# with single quotes
set -l py '
import os
print("There\'s no place like:")
print(os.getenv(\'HOME\'))
'
python3 -c $py
# with double quotes
set -l py "
import os
print(\"There's no place like:\")
print(os.getenv('HOME'))
"
python3 -c $py
If you have a long enough script where escaping the quotes is a problem, consider saving your script off to a file. After all, shells are really good at dealing with files.
If you absolutely want to have something resembling a HEREDOC in Fish, you could always pick some unique comment prefix like '###>', prefix your python script with that, and read that into a variable like so:
# Makeshift heredoc
###> import os
###> print("There's no place like:")
###> print(os.getenv('HOME'))
set -l py (grep "^###>" (status -f) | cut -c 6- | string collect)
python3 -c $py
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论