Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos bash:ps grep用于使用Umlaut(OS X)的进程_Macos_Bash_Shell_Grep - Fatal编程技术网

Macos bash:ps grep用于使用Umlaut(OS X)的进程

Macos bash:ps grep用于使用Umlaut(OS X)的进程,macos,bash,shell,grep,Macos,Bash,Shell,Grep,在shell脚本中,我需要确定特定的应用程序是否仍在运行。如果我们的应用程序名称不包含任何Umlauts(äöüè…),那么这将是一项简单的任务。我如何才能可靠地“grep”我的过程中的问题 $ export LC_ALL="en_US" $ echo "amétiq siMed Büro.app" | grep ü amétiq siMed Büro.ap

在shell脚本中,我需要确定特定的应用程序是否仍在运行。如果我们的应用程序名称不包含任何Umlauts(äöüè…),那么这将是一项简单的任务。我如何才能可靠地“grep”我的过程中的问题

$ export LC_ALL="en_US"                                                                      
$ echo "amétiq siMed Büro.app" | grep ü
amétiq siMed Büro.app
shell脚本获取应用程序名称作为参数,“amétiq siMed Büro.app”在本例中。有多个自定义副本同时运行,它们的名称不同,脚本应该只检查一个特定的应用程序(通过param获取的应用程序),而忽略其他应用程序

$ export LC_ALL="en_US"                                                                      
$ echo "amétiq siMed Büro.app" | grep ü
amétiq siMed Büro.app
对特定应用程序名称(param)使用grep时,完全没有点击:

$ export LC_ALL="en_US"                                                                      
$ echo "amétiq siMed Büro.app" | grep ü
amétiq siMed Büro.app
点击次数太多:

bash> ps ax | grep "/[A]pplications/am" 
 4335   ??  S      5:19.01 /Applications/ame?M^Atiq siMed Bu?M^Hro.app/Contents/MacOS/siMed2
10188   ??  S      0:03.18 /Applications/ame?M^Atiq siMed SUPPORT.app/Contents/MacOS/siMed2
$ export LC_ALL="en_US"                                                                      
$ echo "amétiq siMed Büro.app" | grep ü
amétiq siMed Büro.app
尝试手动缩小grep时再次无点击:

bash> ps ax | grep "/[A]pplications/am" | grep "Büro"

bash>
$ export LC_ALL="en_US"                                                                      
$ echo "amétiq siMed Büro.app" | grep ü
amétiq siMed Büro.app
grep似乎在Umlaut字符第一次出现的位置之后停止工作

$ export LC_ALL="en_US"                                                                      
$ echo "amétiq siMed Büro.app" | grep ü
amétiq siMed Büro.app
我还尝试了lsof,但没有成功。你知道下一步该怎么做吗

$ export LC_ALL="en_US"                                                                      
$ echo "amétiq siMed Büro.app" | grep ü
amétiq siMed Büro.app

运行OS X 10.7-10.9时,必须设置区域设置以匹配重音,例如:

$ export LC_ALL="en_US.UTF-8"
$ echo "amétiq siMed Büro.app" | grep ü
$ export LC_ALL="en_US"                                                                      
$ echo "amétiq siMed Büro.app" | grep ü
amétiq siMed Büro.app
结果

$ export LC_ALL="en_US"                                                                      
$ echo "amétiq siMed Büro.app" | grep ü
amétiq siMed Büro.app
ps
示例:

$ export LC_ALL="en_US"                                                                      
$ echo "amétiq siMed Büro.app" | grep ü
amétiq siMed Büro.app
$ export LC_ALL="en_US"
$ tail -f ü.k &
[1] 57945
$ ps -ef | grep ü[.]
klashxx   57945 27535  0 15:02 pts/6    00:00:00 tail -f ü.k
tl;博士
  • 使用
    pgrep
    代替
    ps
    +
    grep
  • 使用
    iconv-t UTF8-MAC
    将搜索字符串转换为NFD(标准化分解的Unicode)格式

pgrep-qlf“$(iconv-t UTF8-MAC似乎我用osascript/AppleScript解决问题太快了-我能够在终端中过滤我的有问题的进程,但由于某种原因它在我的脚本中不起作用

$ export LC_ALL="en_US"                                                                      
$ echo "amétiq siMed Büro.app" | grep ü
amétiq siMed Büro.app
因此,我发现解决这个问题的方法是:如果我无法使用ps、lsof等命令可靠地“grep”应用程序路径,与脚本作为param获得的路径匹配,那么我只需要在新进程的帮助下重新生成它

$ export LC_ALL="en_US"                                                                      
$ echo "amétiq siMed Büro.app" | grep ü
amétiq siMed Büro.app
总之,我的问题是:

$ export LC_ALL="en_US"                                                                      
$ echo "amétiq siMed Büro.app" | grep ü
amétiq siMed Büro.app
我的脚本获取一个应用程序路径作为参数。此路径包含UMLAUT。此外,应用程序有多个变量,命名不同,其中几个可能同时运行,但脚本需要准确筛选它作为参数获取的变量

$ export LC_ALL="en_US"                                                                      
$ echo "amétiq siMed Büro.app" | grep ü
amétiq siMed Büro.app
/Applications/amétiq siMed Büro.app/Contents/MacOS/siMed2
使用ps、lsof等。我得到了乱码输出,无论我设置了什么语言环境,它都不匹配我的参数:

$ export LC_ALL="en_US"                                                                      
$ echo "amétiq siMed Büro.app" | grep ü
amétiq siMed Büro.app
bash> ps ax | grep "/[A]pplications/am"
70202   ??  S      1:56.38 /Applications/ame?M^Atiq siMed Bu?M^Hro.app/Contents/MacOS/siMed2
75164   ??  U      0:01.75 /Applications/ame?M^Atiq siMed MASTER SN.app/Contents/MacOS/siMed2
只要字符串中包含Umlaut,grep就会失败:

$ export LC_ALL="en_US"                                                                      
$ echo "amétiq siMed Büro.app" | grep ü
amétiq siMed Büro.app
bash> ps ax | grep "/[A]pplications/amétiq siMed Büro.app"
(empty result)
我的解决方案是对应用程序包中存在的文件启动一个“tail&”进程,然后执行一些ps、cut和awk操作,以获得我要查找的应用程序的pid:

$ export LC_ALL="en_US"                                                                      
$ echo "amétiq siMed Büro.app" | grep ü
amétiq siMed Büro.app
cd "/Applications/amétiq siMed Büro.app"  # path the script gets as param
tail -f ./Contents/MacOS/helperfile.txt &
helperpid=$!  # pid of tail process
gr="`lsof -p $helperpid | cut -d'/' -f 2- | grep '/Contents/MacOS/' | sed 's:/Contents/MacOS.*$::' | head -1`"
kill $helperpid  # helper process no longer needed
finalpid=`lsof | grep "$gr" | grep "app/Contents/MacOS" | awk '{print $2}'`
# $finalpid contains the pid of the process in question
请注意,我必须将LC_ALL和LANG设置为“en_US.UTF-8”(可能不需要设置其中一个,我没有进一步深入研究……)

$ export LC_ALL="en_US"                                                                      
$ echo "amétiq siMed Büro.app" | grep ü
amétiq siMed Büro.app

我知道这只是一个解决办法,如果有一个单行线就更好了……至少这个解决方案对我来说很有用。再次感谢参与讨论这个问题的人!

这对echo很有效,但与ps或lsof组合时不会返回任何结果,它们似乎会产生与echo不同的输出。我需要过滤在运行过程中,是否有可能替代使用ps或lsof的方法?+1作为答案,并避免模式中的意外metcharacters使用
grep`printf'%q''pattern`
使用/bin/ps和/usr/sbin/lsof(标准安装OS X 10.9.2)对我来说没有成功…
bash>jobs bash>export LC_ALL=“en_US”;touch”/tmp/amétiq siMed Büro.log“tail-f”/tmp/amétiq siMed Büro.log“&[1]11066 bash>ps ax|grepü[.]bash>ps-ef|grepü[.]bash>jobs[1]+Running tail-f”/tmp/amétiq siMed Büro.log”&bash>
至少关于匹配区域设置的部分是错误的。UTF-8区域设置应该拥有一切。如果我特别使用en_US.UTF-8进行测试,我在从ps输出匹配UMLAUT时没有问题。bash shell中的
locale
输出是什么?它默认输出:LANG=“de_CH.UTF-8”LC_COLLATE=“de_CH.UTF-8”LC_CTYPE=“de_CH.UTF-8”LC_MESSAGES=“de_CH.UTF-8”LC_MONETARY=“de_CH.UTF-8”LC_NUMERIC=“de_CH.UTF-8”LC_TIME=“de_CH.UTF-8”LC_ALL=@svenson:谢谢;我已经找到了问题的症结所在,并对我的答案进行了重大修改——这是一个肮脏的故事。请注意,基于AppleScript的解决方案仅以可识别的形式打印路径——如果你想将其与字符串进行比较,你会再次遇到NFC/NFD问题。这相当于你的AppleScript解决方案——痛苦同样的限制-是
pgrep-lf'siMed'
。请看一下mklement0关于NFC和NFD字符串(合成/分解字符)的精彩答案,这确实非常详细地解释了我的问题。感谢您的插件;我想我已经找到了一个通用解决方案,使用
iconv
UTF8-MAC
;请参阅我更新答案的顶部。
$ export LC_ALL="en_US"                                                                      
$ echo "amétiq siMed Büro.app" | grep ü
amétiq siMed Büro.app