天道酬勤,学无止境

linux

如何处理二进制文件格式的可移植性问题(How to handle portability issues in a binary file format)

问题 我正在设计一种二进制文件格式来存储字符串[不终止 null 以节省空间] 和二进制数据。 一世。 处理小/大端系统的最佳方法是什么? ia 将所有内容转换为网络字节顺序并返回 ntohl()/htonl() 是否可行? ii. x86、x64 和 arm 上的压缩结构的大小是否相同? 三、 他们对这种方法有什么固有的弱点吗? struct __attribute__((packed)) Header { uint8_t magic; uint8_t flags; }; struct __attribute__((packed)) Record { uint64_t length; uint32_t crc; uint16_t year; uint8_t day; uint8_t month; uint8_t hour; uint8_t minute; uint8_t second; uint8_t type; }; 我正在使用开发格式的测试代码: #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <limits.h> #include <strings.h> #include <stdint.h> #include <sys/stat.h> #include <fcntl.h>

2021-09-21 18:51:19    分类:技术分享    c   linux   file   format

程序如何继承环境变量?(How does a program inherit environment variables?)

问题 当我使用标准 C 库中的getenv()函数时,我的程序从其父级继承了环境变量。 例子: $ export FOO=42 $ <<< 'int main() {printf("%s\n", getenv("FOO"));}' gcc -w -xc - && ./a.exe 42 在libc 中, environ变量被声明到environ.c 。 我希望它在执行时为空,但我得到42 。 更进一步的getenv可以简化如下: char * getenv (const char *name) { size_t len = strlen (name); char **ep; uint16_t name_start; name_start = *(const uint16_t *) name; len -= 2; name += 2; for (ep = __environ; *ep != NULL; ++ep) { uint16_t ep_start = *(uint16_t *) *ep; if (name_start == ep_start && !strncmp (*ep + 2, name, len) && (*ep)[len + 2] == '=') return &(*ep)[len + 3]; } return NULL; } libc_hidden_def

2021-09-21 18:48:05    分类:技术分享    c   linux   libc

如何在 MonoDevelop 中添加外部引用?(How to add external references in MonoDevelop?)

问题 我已经下载了一个名为 NPlot 的图表库,但我不知道如何将它作为参考添加到我目前正在 MonoDevelop 中制作的 GTK# 应用程序中。 “编辑参考”窗口中没有选项可以添加除列出的外部参考之外的外部参考。 你如何在 MonoDevelop 中添加外部引用? 回答1 作为 Ubuntu 的新手(因此,使用应用程序),我发现解决上述困境非常具有挑战性。 经过数小时的搜索(实际上几乎是半天),我找到了答案。 我为其他可能也面临这个问题的人创建了这篇文章。 在继续之前,请确保您有要添加的dll文件作为参考。 首先,创建一个包含以下内容的 .pc 文件: Name: Description: Version: Libs: -r:<where your dll is> 例子: Name: NPlot Description: Creates charts. Version: 0.9.9.2 Libs: -r:/home/xxx/Downloads/NPlot/nplot-gtk-0.9.9.2/NPlot.dll 本网站的帽子提示。 记住您保存.pc 文件的位置。 我已将文件保存在/home/xxx/Documents 。 接下来,将 .pc 文件复制到/usr/lib/pkgconfig 。 我不确定其他 Linux 发行版,但 Ubuntu 阻止我直接将文件复制粘贴到文件夹

2021-09-21 18:20:29    分类:技术分享    linux   ubuntu   gtk   monodevelop

从 Linux 内核空间禁用反向路径过滤(Disable reverse path filtering from Linux kernel space)

问题 在 Linux 内核模块中,我需要以某种方式禁用 rp_filter。 这通常可以通过几个简单的 sysctl 调用从用户空间实现: sysctl net.ipv4.conf.all.rp_filter=0 sysctl net.ipv4.conf.[ifname].rp_filter=0 如何从内核空间获得相同的结果? 我的第一个想法是我可能需要写入相关的 proc 文件。 如果是这样,这样做的正确方法是什么? 谢谢。 电阻 回答1 我正在查看内核中sysctl的实现,我发现执行sysctl与将值写入/proc文件系统中的文件相同。 在您的情况下,您只想执行以下操作: echo 0 >/proc/sys/net/ipv4/conf/all/rp_filter 这是一个粗略的代码示例,基于我在刚刚阅读的内核代码中看到的内容: struct vfsmount *mnt; struct file *file; ssize_t result; char *pathname = "sys/net/ipv4/conf/all/rp_filter"; int flags = O_WRONLY; mnt = task_active_pid_ns(current)->proc_mnt; file = file_open_root(mnt->mnt_root, mnt, pathname

2021-09-21 17:58:01    分类:技术分享    linux   linux-kernel

pthread_create 内存泄漏(pthread_create memory leak)

问题 我使用 C 语言和 Linux 作为我的编程平台。 在我的应用程序中,我调用 pthread_create。 然后我使用 ps 命令行工具检查我的应用程序的内存使用情况,它在 VSZ 列中添加了 4。 但是问题是当pthread_create函数处理程序退出时,内存中添加的4个没有释放。 然后当应用程序再次调用 pthread_create 时,再次添加一个 4 值,直到它变大。 我试过 pthread_join ,似乎内存还在变大。 谢谢。 回答1 ps不是衡量内存泄漏的正确工具。 当你释放内存时,你不能保证减少进程的 vsize,这是由于内存碎片和避免不必要的系统调用。 valgrind是一个更好的工具。 回答2 您应该在您创建的每个 pthread 上使用 pthread_detach 或 pthread_join(但不能同时使用两者)。 pthread_join 等待线程完成; pthread_detach 表示您不打算等待它(因此该实现可以在线程终止时自由回收与该线程关联的存储)。 同上 Artelius 所说的关于 ps 不是诊断内存泄漏的正确工具。 回答3 当你说但问题是当 pthread_create 函数处理程序退出时 作为线程执行完成后退出的一部分,您是否在执行显式 pthread_exit(NULL)? 此外,pthread_exit()

2021-09-21 17:32:34    分类:技术分享    c   linux

终止一系列进程的最可靠方法(The most reliable way to terminate a family of processes)

问题 如果我们假设,在 Linux 中终止一系列进程的最佳方法是什么: 在我们开始清理之前,家庭中的任意进程都可能被杀死/终止; 因此,如果子进程不终止,它们的 PPID 将为 1 进程可以改变进程组 我正在研究的特定场景是 Bash,但技术越通用越好。 回答1 您可能希望在不同的登录 shell 中执行杀戮(最终通过脚本),以确保您不会意外停止/杀死试图在完成其工作之前进行整体杀戮的 shell/脚本:) 第一个关键策略是不直接终止进程,而是: 首先“冻结”它(使用kill -STOP <pid> )以防止它产生其他孩子(需要可靠地确定它的孩子,否则你会错过一些在这个问答中解释的:https://superuser.com/问题/927836/how-to-deal-with-a-memory-leaking-fork-bomb-on-linux/927967#927967) 将其添加到要终止的进程列表中(稍后) 找到它的孩子列表在孩子们身上重复整个故事,rince重复 一旦基于 ppid 的整个祖先树被冻结,您就可以开始根据进程组定位和冻结祖先 - 只要更改其进程组的进程的父进程仍然存在(因为它们的 ppid),您仍然可以可靠地确定这些进程组未更改) - 将这些组添加到要核对的 pgid 列表中,并冻结您可能在这些组中找到的任何新的基于 ppid 的进程子树,如下所示:

2021-09-21 17:23:32    分类:技术分享    linux   bash   process   terminate

如何从 /var/tmp 更改默认的 Pear/PECL 构建文件夹?(How do you change the default Pear/PECL build folder from /var/tmp?)

问题 我正在尝试在 Linux 上安装 PECL 包,但安装程序永远不会超过配置阶段。 我的托管服务提供商在 /var/tmp 安装了一个文件系统,阻止文件执行,这导致了这个错误: root@host [/usr/local/apache/conf/includes]# pecl install pdo downloading PDO-1.0.3.tgz ... Starting to download PDO-1.0.3.tgz (52,613 bytes) .............done: 52,613 bytes 12 source files, building running: phpize Configuring for: PHP Api Version: 20041225 Zend Module Api No: 20060613 Zend Extension Api No: 220060519 building in /var/tmp/pear-build-root/PDO-1.0.3 running: /root/tmp/pear/PDO/configure checking for egrep... grep -E checking for a sed that does not truncate output... /bin/sed checking for

2021-09-21 17:14:23    分类:技术分享    php   linux   pear   pecl

cx_Oracle 无法识别用于在 Linux 上安装的 Oracle 软件安装位置(cx_Oracle does not recognize location of Oracle software installation for installation on Linux)

问题 我已经能够在我的 Windows 8 笔记本电脑上成功安装 cx_Oracle 以与 Python 3.4 一起使用,现在我正在尝试将相同的设置(带有 Python 3.4 的 cx_Oracle)安装到 Linux 机器上。 从 cx_Oracle-5.1.3.tar.gz 运行 setup.py 文件时,我最终遇到此错误: sudo python3 setup.py install Traceback (most recent call last): File "setup.py", line 135, in <module> raise DistutilsSetupError("cannot locate an Oracle software " \ distutils.errors.DistutilsSetupError: cannot locate an Oracle software installation 按照我查看的其他一些答案(Windows 上的easy_install cx_Oracle(python 包),https://gist.github.com/jarshwah/3863378)我已经安装了这 3 个即时客户端 rpm: rpm -ivh oracle-instantclient12.1-basic-12.1.0.2.0-1.i386.rpm

2021-09-21 16:12:15    分类:技术分享    python   linux   oracle   cx-oracle

如何在子shell中找出父shell的用户?(How to find out the user of parent shell inside a child shell?)

问题 假设父 shell 的用户是foo 。 如果你运行类似sudo -u bar -i ,那么你就在一个带有用户bar的子 shell 中。 那么,如何在子shell中找出父shell的用户呢? 即,在上述情况下,我怎么知道父 shell 的用户是foo ? 更新我知道,通过一些 hack,可以使用ps来实现这一点。 但是,如果可能的话,我会对一种不那么笨拙和更标准的方式更感兴趣。 更新 2 在答案的帮助下,我最终采用了以下解决方案: # from parent shell, user is foo $ sudo -u bar -i PARENT=foo # from child shell, show parent user foo $ ps u -p $PPID | grep PARENT | cut -d= -f2 回答1 您可以使用$PPID变量和一两个命令来帮助您: #!/bin/bash USER=`ps u -p $PPID | awk '{print $1}'|tail -1` echo $USER 回答2 首先,bash 有一个很好的内置变量$PPID ,它保存其父进程的进程 ID。 其次, /proc/<pid>/status | egrep '^Uid:' | awk '{ print $2 }' /proc/<pid>/status | egrep '

2021-09-21 16:12:04    分类:技术分享    linux   bash   shell

Linux - 如何在没有 find 命令的情况下查找过去 12 小时内更改的文件(Linux - How to find files changed in last 12 hours without find command)

问题 我需要找到过去 12 小时内修改过的文件。 但是,该目录非常大,因此使用通常的 find 命令花费的时间太长。 有没有人有任何想法可以更快地做到这一点? 我正在考虑列出文件,然后使用 head 获取前 20 个文件,然后仅检查这些文件。 但我不确定。 有什么帮助吗? 更新:感谢所选答案的帮助,我们发现您实际上可以在不使用 find 命令的情况下找到文件。 诀窍是给文件名加上时间戳,然后使用以下代码获取最新的: ls -1 /directory/files*.txt | sort -nr | head -1 回答1 文件修改时间存储在其 inode 中。 因此,无论您使用什么命令,都必须读取该目录中所有文件的 inode。 您可以制作自己的脚本来检查 mtime,但速度不会更快。 列出目录内容(仅文件名)非常快,请尝试使用ls -1 ( ls 减去 1 )。但是使用 mtime 等文件属性列出它很慢: ls -l ( ls 减去小 L )。 文件系统以“随机”顺序读取目录中的文件列表(顺序取决于很多事情,但是是静态的)。 所以你不能使用像在 X 个文件之后停止之类的东西。 ls -t列出按 mtime 排序的文件,但它必须读取所有文件的 mtime 才能对其进行排序。

2021-09-21 16:04:09    分类:技术分享    linux   bash