我的电脑运行 Ubuntu 14.04。GDB在不同的账户中似乎异常。例如我做了一个非常简单的测试。我在下面写了一个文件~/test/test.c:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
printf("hello,world");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
并使用命令"gcc -g test.c -o test"构建,然后我得到名为 test 的结果文件。下一步,运行 gdb 进行调试。请注意,当前帐户是我自己的用户。
$gdb test
(gdb)l //work well
(gdb) b 6 //work well
(gdb) r //error: Cannot exec /home/xxx/test/test -c exec /home/xxx/test/test .
//Error: No such file or directory
Run Code Online (Sandbox Code Playgroud)
但是如果我通过命令“su”更改为 root 帐户,gdb 运行良好。为什么?
我使用fish shell,并希望能够“获取”一些用sh兼容语法编写的shell脚本,而fish无法读取这些脚本。例如,许多软件希望您提供一些 shell 脚本来导出有用的环境变量:
# customvars.sh
FOOBAR=qwerty
export FOOBAR
Run Code Online (Sandbox Code Playgroud)
如果我不关心保留局部变量和函数定义,一种解决方法是使用 exec 用 /bin/sh 替换当前进程,然后返回到fish
# We start out on fish
exec /bin/sh
Run Code Online (Sandbox Code Playgroud)
# Running a POSIX shell now
. customvars.sh
exec /usr/bin/fish
Run Code Online (Sandbox Code Playgroud)
# Back on fish
echo $FOOBAR
Run Code Online (Sandbox Code Playgroud)
有没有办法将这种模式归结为一个单行代码,我可以将其保存在某个函数中?如果我尝试做
exec /bin/sh -c '. vars.sh; /usr/bin/fish'
Run Code Online (Sandbox Code Playgroud)
我的终端模拟器窗口立即关闭,而不是带我回到交互式鱼提示。
有没有办法让 exec 系统调用像返回而不是完全替换当前进程映像的函数调用一样工作?我的动机是试图用不兼容的语言集成两个 shell。这个想法是 shell A 将能够执行用 shell B 语言编写的脚本,并且仍然保留对 shell B 脚本所做的环境变量、工作目录等的任何更改。
到目前为止,我能想到的所有解决方案都有一些很大的局限性。
第一个解决方案是让 shell A exec 进入 shell B,然后让 shell B exec 回到 shell A,就像我在我之前问的这个问题中所做的那样。问题在于,这会丢弃初始 shell A 进程的任何状态,例如在当前运行的脚本中的位置、局部变量、别名等。
第二种解决方案是让外壳 A 使用 fork-exec 作为传统子进程运行外壳 B,并让外壳 B 在退出之前序列化其环境并将其发送回外壳 A 进程。这样做的两个好处是它保留了父进程的状态,并且如果我们愿意,我们还可以序列化应用程序级数据,例如函数和别名。问题是子进程从父进程继承了很多东西,很难确保我们没有忘记序列化其中的一个。
假设我的非 root 32 位应用程序在 64 位系统上运行,其中所有文件系统都以只读方式挂载。该应用程序在内存中创建了一个 64 位 ELF 的图像。但是由于只读文件系统,它无法将此图像转储到文件中进行操作execve。是否仍有支持的方式从此映像启动进程?
注意:这里的主要问题是从 32 位模式切换到 64 位模式,而不是进行任何可能不可靠的黑客攻击。如果这解决了,那么整个问题就变得微不足道了——只需制作一个自定义加载器。
exec echo "some "; echo "test"在 bash 中运行永远不会打印“一些测试”吗?
我会寻求对这个问题的确认,因为我正在编写一个小的 shell 脚本,并且我希望它exec在调用命令后不要继续执行任何操作。
我认为我不需要担心,根据我的理解,经过咨询:
man 3 exec man 1p exec shell 脚本,当由 shell 执行时,会生成
exec,其中exec***家族系统调用来替换正在执行脚本的 shell/bash,这会阻止shell 的进一步操作(已被“替换”)如前所述,这个问题的主要目标是为我的推理寻求确认,以防止在执行 exec (例如echo test)之后脚本中发生任何事情。
我希望尽可能提供一般性答案(POSIX),但以防万一,我对 GNU/Linux 和 GNU/Bash 最感兴趣
从命名管道读取的进程通常会在写入管道的进程完成写入(发送 EOF)时终止。在某些情况下,您可能有不同的进程间歇性地写入管道,并希望单个进程连续从管道读取。为此,您可以设置一个“虚拟”编写器来打开管道但不写入它:
$ mkfifo myPipe
$ cat > myPipe &
Run Code Online (Sandbox Code Playgroud)
虚拟写入器保持命名管道打开 - 不向其中输入数据或永远不会关闭。因此,读取器进程能够从所有(其他)合法写入器接收输入,而无需终止和重新生成。
我见过一些人使用exec 3>而不是cat作为保持命名管道打开的方法。
$ mkfifo myPipe
$ cat < myPipe &
[1] 10796
$ exec 3> myPipe
$ echo "blah" > myPipe
blah
Run Code Online (Sandbox Code Playgroud)
这种方法似乎有效,而且您在后台没有需要担心(或清理)的虚拟作家,所以我喜欢它。问题是,我并不真正了解它。
如何exec 3>在没有要执行的实际文件或可见(后台)进程的情况下保持命名管道打开的任务,这种方法有什么缺点吗?
(我知道它最终必须打开命名管道的输入文件描述符以进行写入,所以我对这exec 3部分exec 3>正在做什么特别感兴趣。)
当linux有execve()一个ELF时,它会将该ELF映射到进程的内存空间中,并从入口点开始运行代码。但是内核是如何决定ELF的加载地址和入口点的呢?
如果禁用 ASLR,它将查找.p_vaddr每个 PT_LOAD 段并使用.e_entryELF 标头作为入口点。
但是如果启用 ASLR 会怎样呢?内核是否会简单地向上述所有内容添加随机移位,但保持它们的相对位置?
ELF的内容会影响内核的行为吗?就像.p_vaddrPT_LOAD 段的最小值是零还是非零?比如.e_typeELF header是ET_DYN还是ET_EXEC?
我特别谈论的是 x86_64。
有没有办法在find . -exec somecommand {} \;不实际运行命令的情况下查看替换的结果?像试运行(或试运行或打印)?
例如,假设我有以下文件结构:
/a/1.txt
/a/2.txt
/a/b/3.txt
Run Code Online (Sandbox Code Playgroud)
有没有办法find . type f -exec rm {} \;从a目录中进行测试,以便输出将打印到 stdout 但不执行,例如:
rm 1.txt
rm 2.txt
rm b/3.txt
Run Code Online (Sandbox Code Playgroud)
更新
说明:rm只是一个示例命令,我对一般情况感兴趣
l并v在 exec 调用中表示参数是通过 list 还是array(vector). 我在某处读到它p表示用户的路径并e表示环境,但不明白这意味着什么?
上下文:zsh Catalina MacOS:
可执行脚本BatesStamp使用 imagemagick 将数字标记到 jpg 文件:
# BatesStamp: OVERWRITES and stamps ONE file with COUNTER (upper left corner)
# usage ./BatesStamp COUNTER PATH_FILE
# to be used with find & -exec: https://unix.stackexchange.com/a/96239/182280
COUNTER=$1 # 1st argument = number to be stamped upon .jpg file
PATH_FILE=$2 # 2nd argument = /path_to_file/Filename.jpg
convert $PATH_FILE -auto-orient -gravity northWest -font "Arial-Bold-Italic" -pointsize 175 \
-fill red -annotate +30+30 "$COUNTER" $PATH_FILE;
((COUNTER++)) #/sf/answers/1472460251/
echo "watermarked i= $COUNTER $PATH_FILE"
Run Code Online (Sandbox Code Playgroud)
目标是用唯一的编号标记目录树中的所有 .jpg 文件。我相信每次调用 …
exec ×10
process ×3
shell ×3
find ×2
aslr ×1
elf ×1
fifo ×1
fish ×1
gdb ×1
linux ×1
linux-kernel ×1
shell-script ×1
system-calls ×1