Is there a way to stop 'child exited with status 1' error when running st -e 'curl wttr.in/LOCATION | less -R'?

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

Is there a way to stop 'child exited with status 1' error when running st -e 'curl wttr.in/LOCATION | less -R'?

问题

我正在尝试让脚本打开一个新的st终端窗口并执行curl -s wttr.in/LOCATION | less -R

st -e "curl wttr.in/LOCATION | less -R"会打开终端窗口,但会迅速关闭并在父窗口中返回child exited with status 1
我不想在/local/bin中创建一个命令来执行此请求。是否有更好的方法?

英文:

I'm trying to get a script to open a new st terminal window and execute curl -s wttr.in/LOCATION | less -R.

st -e "curl wttr.in/LOCATION | less -R" opens the terminal window briefly, but closes and returns child exited with status 1 in the parent window.
I don't want to have to make a command in /local/bin just to make that request.
Is there a better way?

答案1

得分: 1

背景

设计良好的终端程序接受参数向量,可以直接使用 execve()(或者更新的 posix_spawn() 系列系统调用)来调用,而不是用 system() 来调用shell命令。这样可以更安全地使用它们,避免需要对要作为参数传递到单个shell命令中的内容进行引用和转义(否则可能会容易受到注入攻击)。一些旧版本的终端程序接受 system()-ready 的 sh 字符串(至少是为了兼容性),但你正在使用来自 https://suckless.org/ 的软件 - 他们已经决定做得更好。


简短/简单/不安全的修复

你正在使用的终端程序在 -e 后面接受一个命令和参数列表,作为单独的参数。因此,你需要像这样做:

st -e sh -c 'curl wttr.in/LOCATION | less -R'

在这里,sh 是要在终端中运行的命令,-c 是它的第一个参数,curl wttr.in/LOCATION | less -R 是它的第二个参数。


安全地执行这个操作

然而,如果你的位置来自一个变量,那么你应该将它与作为脚本传递的内容分开:

location="wttr.in/LOCATION"
st -e sh -c 'curl "$1" | less -R' sh "$location"

在这里,你的脚本 curl "$1" | less -R 使用 $0 作为 sh 来运行(在错误消息中用于描述失败的程序名称;你可以随意更改它),使用 $1 作为 wttr.in/LOCATION。将URL传递给 $1 意味着包含像 $(rm -rf ~) 这样的字符串的URL不会删除你的主目录,就像使用不够谨慎的方法一样。

英文:

Background

Well-designed terminal programs take argument vectors that can be invoked directly with execve() (or the newer posix_spawn() family of syscalls), not shell commands for invocation with system(). This makes them easier to use securely, avoiding the need to quote and escape contents to be passed as arguments into a single shell command (where without that escaping one is vulnerable to injection attacks). Some legacy terminals take system()-ready sh strings (at least for compatibility), but you're using software from https://suckless.org/ -- they've taken it on themselves to do better.


The Short/Simple/Insecure(?) Fix

The terminal you're using takes a command and argument list after -e as separate arguments. Therefore, you want something like:

st -e sh -c 'curl wttr.in/LOCATION | less -R'

Here, sh is the command to run in the terminal, -c is its first argument, and curl wttr.in/LOCATION | less -R is its second argument.


Doing This Securely

If your location is coming from a variable, however, then you should keep it out-of-band from the content passed as a script:

location="wttr.in/LOCATION"
st -e sh -c 'curl "$1" | less -R' sh "$location"

Here, your script curl "$1" | less -R is run with a $0 of sh (used in error messages to describe the name of the program that failed; change it however you like) and a $1 of wttr.in/LOCATION. Passing the URL in $1 means that a URL containing a string like $(rm -rf ~) won't delete your home directory, as it might with less incautious approaches.

huangapple
  • 本文由 发表于 2023年6月1日 02:47:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/76376467.html
匿名

发表评论

匿名网友

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

确定