如何在fish脚本中嵌入Python代码?

huangapple go评论72阅读模式
英文:

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 &lt;&lt; EOF
#INSERT_PYTHON_CODE_HERE
EOF
)

RESPONSE=$(COLUMNS=999 /usr/bin/env python3 -c &quot;$PYCODE&quot; $@)

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 &quot;
#INSERT_PYTHON_CODE_HERE
&quot;

set RESPONSE (COLUMNS=999 /usr/bin/env python3 -c &quot;$PYCODE&quot; $argv)

but this falls apart when you have a Python script that can include both &#39; and &quot; (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 &quot;/#INSERT_PYTHON_CODE_HERE/r $BASE_DIR/test_sh.py&quot; $BASE_DIR/../src/mfa.fish)

答案1

得分: 1

&gt; PYCODE=$(cat &lt;&lt; EOF
&gt; #INSERT_PYTHON_CODE_HERE
&gt; EOF
&gt; )

这种表示字符串的方式叫做heredoc。Fish不支持heredocs,[详细的替代方案在这里](https://fishshell.com/docs/current/fish_for_bash_users.html#heredocs)。

&gt; 相应的Fish命令似乎是这样的
&gt;
&gt; set PYCODE &quot;
&gt; #INSERT_PYTHON_CODE_HERE &quot;
&gt;
&gt; 但是当你的Python脚本中同时包含单引号和双引号时,这种方式就不奏效了

不,它不会 - 你只需要使用反斜杠来转义引号,就像这样:

    # 使用单引号
    set -l py '&#39;
    import os
    print(&quot;There\&#39;s no place like:&quot;)
    print(os.getenv(&#39;HOME&#39;))
    '&#39;
    python3 -c $py
    
    # 使用双引号
    set -l py &quot;
    import os
    print(\&quot;There&#39;s no place like:\&quot;)
    print(os.getenv(&#39;HOME&#39;))
    &quot;
    python3 -c $py

如果你有一个足够长的脚本,需要转义引号的话,考虑将脚本保存到一个文件中。毕竟,shell非常擅长处理文件。

如果你绝对希望在Fish中有类似HEREDOC的东西,你可以选择一些唯一的注释前缀,比如'###&gt;',在你的Python脚本前面加上它,然后像这样将其读入一个变量:

    # 模拟heredoc
    ###&gt; import os
    ###&gt; print(&quot;There&#39;s no place like:&quot;)
    ###&gt; print(os.getenv(&#39;HOME&#39;))
    
    set -l py (grep &quot;^###&gt;&quot; (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 &#39;
import os
print(&quot;There\&#39;s no place like:&quot;)
print(os.getenv(\&#39;HOME\&#39;))
&#39;
python3 -c $py

# with double quotes
set -l py &quot;
import os
print(\&quot;There&#39;s no place like:\&quot;)
print(os.getenv(&#39;HOME&#39;))
&quot;
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
###&gt; import os
###&gt; print(&quot;There&#39;s no place like:&quot;)
###&gt; print(os.getenv(&#39;HOME&#39;))

set -l py (grep &quot;^###&gt;&quot; (status -f) | cut -c 6- | string collect)
python3 -c $py

huangapple
  • 本文由 发表于 2023年2月19日 10:10:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75497581.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定