免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 11417 | 回复: 13
打印 上一主题 下一主题

[其他] tcsh,shebang和clojure [复制链接]

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-10-09 03:28 |显示全部楼层 |倒序浏览
本帖最后由 starwing83 于 2012-10-09 03:29 编辑

恩,今天和OwnWaterloo发生了一场争执。争执到后来我好像都没啥自信了,所以想看看大家对于这个问题有什么看法。

@Ager @OwnWaterloo

事情最开始是这样的,OW想用clojure写脚本,使其能独立运行。UNIX上面最简单的办法是shebang,即:

  1. #!/usr/bin/env java clojure.main

  2. (prn "Hello World")
复制代码
shebang是一种能让文本文件被当做可执行文件执行的方式,shell如果发现一个文件的头两个字符是#!,它会提取后面的所有参数,并带上这个文本文件的文件名来组成一个命令行并执行,比如上面这个程序假设叫test,shell会组装一个命令行“/usr/bin/env java clojure.main ./test”,然后执行这个命令行。最终的结果就是好像这个文本文件能被直接执行一样。这个技术叫做shebang。

但是,bash的shebang有问题,它会将这个程序在shebang中提取的所有参数都当做一个参数来传递给实际的程序,比如说上面这个命令行,env程序实际收到的参数是"java clojure.main"和"./test",而env显然不知道这个带空格的"java clojure.main"是何方神圣,自然就执行失败了。

OwnWaterloo觉得,clojure至少应该提供一个标准的可执行的文件(可能是shell脚本,或者其他的什么的),这个文件可以作为直接执行clojure程序的工具。假设这个文件叫clj,那么shebang可以这么写:

  1. #!/usr/bin/env clj

  2. ....
复制代码
在这种情况下,clj是第一个参数,./test是第二个参数,env会在环境中查找clj的位置并执行,就不会有问题了。OwnWaterloo觉得,即使是不提供这么一个工具,哪怕是给一个标准化的名字,也可以让这个工作变得轻松。clojure这么做很不考虑那些希望让clojure的程序能够当做脚本独立运行的人的感受。

我个人觉得clojure本身是基于java-vm的一种语言。它本身其实并不考虑作为脚本这么一个用途,所以不提供这样的命名约定什么的其实也是合理的。不过OwnWaterloo这个观点似乎有点“王垠”化,用他的原话说:

OwnWaterloo 2:33:24
只有自己遇见的需求才是需求, 其他人的需求就是无理取闹?
其他人不以自己的习惯做法并并且没达到目标, 就一定是其他人的方法不对?
你什么时候变成王垠那种货色了?


必须提到的是,OwnWaterloo自己已经提供了一个方案来做这件事情,其实就是“可以同时被当做shell脚本和clojure程序的脚本”

  1. #!/bin/sh

  2. ":"; /usr/bin/env java clojure.main "$0" $*

  3. (prn "Hello World")
复制代码
我在考虑这么一个问题,就是软件本身的设计目的,和用户的需求不明确的时候,用户到底应该怎么办。我对OwnWaterloo说,你应该去clojure邮件列表发言,说明这个问题,而不是跟我讨论,因为这完全没有用。不过我也不知道OwnWaterloo自己的看法是如何,大概是“我已经想到一种解决方案了,我为什么要等待别人去解决这个问题呢?”

我自己其实也遇到了这种关于“需求”的情况。我用tcsh,tcsh本身的shebang我很少用(其实我是根本就没用过,脚本我都是直接用Vim执行,或者在命令行会写解释器来执行,很少会直接执行脚本),所以在测试的时候,我发现tcsh的windows版本竟然不认shebang,然后经过了Stack Overflow提问、自行编译等等方式最后都没有解决这个问题。这本质上依然是“软件的开发者没有满足使用者的需求”。我认为,我遇到的情况是不合理的,因为作为一个shell,在任何系统上行为一致应该是很有必要的。tcsh不支持shebang的原因是它支持Windows式的“按照后缀名判断文件类型”,可是在这之前,先打开文件并检测一下#!应该是很简单的。而且tcsh的源代码中的确也表示Win32移植版本应该支持HASHBANG特性。

我认为我遇到的现象和OwnWaterloo遇到的现象是不一样的。Clojure的官方主页上完全没有提到过支持在shell中直接执行clojure程序的做法。而tcsh作为一个shell,是必须满足POSIX对shell的要求的——即至少在某种情形下识别shebang。所以这并不是一种情况。对clojure来说,这种用途是作者“完全没有考虑过,或者没有考虑透彻的使用情景”,而对tcsh来说,这应该是“宣称的功能没有达到”。

因为#字符在clojure中并不是注释符。可以发现clojure的确是对clojure程序中包含shebang做出了支持。问题在于这个支持不全面,并不能保证clojure一定能够通过shebang调用到。一方面,shell不支持shebang参数分割是一个缺陷,另一方面,clojure本身没有提供独立的可执行的工具来直接执行clojure程序也是一个问题。两者共同造成了clojure无法通过shebang执行的情况。

这其实是另一个话题了,在两个软件的缺陷同时造成一个困难的时候,谁应该为这个困难负责?OwnWaterloo认为应该是clojure,我不知道这是基于什么情况的考虑,反正我觉得应该负责的是shell。因为归根结底,是shell的shebang不完善造成的,clojure提供独立执行文件的方式只是一个work around而已,而shell的shebang仍然不完善。

这次争吵让我正视了关于软件开发中,需求和设计目标不匹配的一系列问题。包括没有完成设计目标、出现了设计者没有考虑过的情况、数个应该共同协助完成目的的特性之间的不协调等等问题。我想知道大家的看法。


我想知道:
1. 软件的开发者选择软件的应用场景,并决定软件支持的限度(如clojure不提供独立执行文件),究竟是不是开发者自己的自由。
2. 软件没有达到宣称的目标,和软件在自己没考虑过的范畴没有达到设计目的,是不是同样的情况。
3. 对于遇到这个问题的用户的抱怨,向其说明“产品并没有考虑在这种情况使用,这是产品的自由”,是否是正确的行为。
4. 如果你是使用者,你在向人抱怨自己的“正常”使用没有达到预期的目标,反而需要自己去想work around,并埋怨其设计糟糕的时候,如果有人提出相反意见,你是否能保持冷静并考虑。
5. clojure究竟有没有考虑作为shebang程序使用?是设计者考虑不周,还是设计者的shell本身是支持参数分割的,还是设计者自己私人使用了一个独立的可执行驱动呢?
6. 对待这种情况,作为抱怨者,和作为被抱怨者,以及作为聆听抱怨者,应该采取什么样的行为是合适的?

希望能和大家深入讨论这个问题。

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
2 [报告]
发表于 2012-10-09 18:39 |显示全部楼层
本帖最后由 starwing83 于 2012-10-09 18:39 编辑

回复 9# OwnWaterloo


    我想我大概知道矛盾在哪儿了……

除非有十分明显的漏洞,否则假设对方的需求是合理的, 只是自己没遇见过而已; 然后直面问题; 尝试解决或者提供work around; 之后再是点评、吐槽什么的 —— 我记得你之前一直是这样的。


你怎么知道我不是这样的呢?难道我没有找work around吗?

去stack overflow提问如何让clojure支持shebang。

测试tcsh对shebang的支持(因为shebang不分离参数是bash的问题)——最后,大概是昨晚5点的样子吧,得到结论了。shebang是系统的事儿。跟shell没关系。系统自己的exec系列系统调用处理shebang的。还有tcsh的windows版本不支持shebang问题也解决了,是个环境变量:TCSHONLYSTARTEXES,天杀的文档。好,这个“子过程”返回。

我没没有对你的work around有任何恶意的评价吧?相反我觉得这是个解决方案。而且,我对你的说法的评价,都是在你提出这个work around很久以后吧。在这之前,似乎我一直在想办法去找你的问题的解决方案吧?在这之前我一直都没有说你的需求不合理吧??

另外想问一下,既然你也知道,emacs lisp并不是以作scripting language为主要目的,而你也这么用了。而且我也没有评价这个不合理,为什么你觉得我说“开发者并没有考虑到这个情况”就是“这个情况是不合理的”?我从来没有在这两者之间画上等号啊?我仅仅是说,这个情况clojure没有考虑,要你去mailing list去问而已,我根本就没有说过这个想法是很不合理的啊?我说过最接近的一个话是“clojure不是用作脚本设计的,所以不提供启动器也是天经地义的吧”,问题是,“不是作脚本设计”和“作脚本设计就不合理”这个之间是不是没有等价关系?光盘不是做衣服的不是做建筑塑料的可是就是有人用光盘盘片做这些艺术品啊,没有不合理啊。

好,继续说work around。既然你提到了那个解决方案。我的注意力就放到了“如何让shell支持多参数shebang上”。因为添加一个clj是很简单的事情,然而你说clojure没提供,而且连名字都没有标准化——事实上,我觉得有问题的地方是,他没提供这一点是事实,如果你想从这一点出发,要么你自己提供一个,然后等官方提供了以后再改;要么你立刻要求官方提供一个,要么你黑了官方网站自己加一个——不管怎么说,你对我说这个话完全没有意义啊!我不是clojure的维护者啊。你对我抱怨,我也只能有两个态度:1.“啊,clojure好差劲啊,这样的东西都不提供,真是的,完全不考虑使用者的感受和正常需求嘛”——然后又能怎么样?联名上书吗?就是因为考虑到这一点,我才采用了第二个态度2.“你跟我抱怨是没用的,clojure自己本身就没用提供这个东西就已经是事实了。如果clojure真的没提供,那么显然它无法阻止别的用户自己写driver脚本,那么driver脚本的名字不统一估计也是事实了,既然是事实,你对我说又有什么用呢?”

我有说你的需求不合理吗?我在说“这是事实”好吗?

又跑题了……还是说work around,我在找shebang如何支持多个参数上面(前文提到了,从clojure入手是没法解决问题的——至少没法彻底解决OwnWaterloo所有的问题),假设我们可以写特殊的shebang,然后这个shebang能分离参数,那么就很不错了。

不过我查询了POSIX(这时已经早晨7点左右了),才知道shebang不是shell的行为,POSIX规定shell的脚本第一行如果是#!开头是“unspecified”的,然后我查了exec,发现只有很小一段文字提到了。而且是说“直接调用#!后面的代码,然后将程序以stdin的形式喂给解释器”。这样其实就很奇怪了。如果是这样,#!后面就应该是**完整**的命令行,而不应该是我在1L说的待组装的命令行了。而这样的话,操作系统分离参数应该是很正常的事情才对啊!

那么,就只剩下一个可能了:我这里用的是windows,而windows是没有shebang的(甚至连exec系列函数都没有!),所以shebang只有可能是mingw模拟的。那么这应该是minggw的bug。现在应该找一个Linux环境,看看会不会分隔参数,如果会,向MinGW提交Bug,如果不会,向Linux提一下问题。

这才是解决方案吧?——当然,1L已经提到了,你已经通过另外一个方式解决了问题,这些只是为了从根本原因上——shell的shebang和clojure没有driver——上出发去解决。我似乎并没有说过你的使用场景不合理。包括我在1L的帖子都完全没有这个意思。我只是说开发者没考虑这个场景、或者这个场景不是开发者的设计目标、或者开发者对这个使用方式的实现有bug,我自始自终没有说过这不合理吧?而且我的确是一开始就去找work around啊,一开始推荐你自己写一个driver,你说不合理,我就又去鼓捣tcsh到去看一个shell的源代码到底怎么处理的,然后去Stack Overflow注册账户,提问,然后又去看POSIX,难道我不是为了解决问题才这样么?难道是抽风了?

仅仅描述一下事实,怎么就刺痛你了呢?非要别人跟着你一起抱怨让你有共鸣你才开心么?这样能解决问题吗?

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
3 [报告]
发表于 2012-10-09 18:44 |显示全部楼层
本帖最后由 starwing83 于 2012-10-09 18:45 编辑

我擦……写了这么多,居然忘了写结论!!!

那么,就只剩下一个可能了:我这里用的是windows,而windows是没有shebang的(甚至连exec系列函数都没有!),所以shebang只有可能是mingw模拟的。那么这应该是minggw的bug。现在应该找一个Linux环境,看看会不会分隔参数,如果会,向MinGW提交Bug,如果不会,向Linux提一下问题。


tcsh在Windows上的shebang是**会**分割参数的!

所以,只有一种可能了:即不分割参数应该是mingw或mingw的后端cygwin的Bug!!

这事儿应该向他们提才对……

下面的代码,在tcsh上面,完美运行:
  1. #!/mingw/git/bin/env java clojure.main

  2. (prn "Hello World\n")
复制代码
root暂时只有bash支持,我将就这么写了。不然找不到env。

但是,这个代码执行了!这证明至少tcsh的shebang模拟支持是可以分离参数的!

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
4 [报告]
发表于 2012-10-09 18:55 |显示全部楼层
= =我的想法有问题么……clojure毕竟不是windows嘛……但是如果最终不支持也没办法嘛……我的策略一般是:

1. 搜索看是否有支持的隐藏开关(tcsh里面就有一个……)
2. 邮件列表提问
3. 如果没人回,自己写一个patch,再在邮件列表ANN

Windows完全无力啊,不开源啊……

好吧,就算clojure和Windows一样,rich对于自己不关心的特性完全不理,而且绝对不带入版本库。

——你对我抱怨也没用啊……我最终也只会上面提到的三板斧啊,而且最终你解决了问题也很好啊……

最多赞扬一下混合语言方案比较“巧妙”……

就算是吐槽了,总觉得这种吐槽有点奇怪……

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
5 [报告]
发表于 2012-10-09 18:58 |显示全部楼层
回复 13# OwnWaterloo


    其实我对这些都没意见,你说的都对,我只是对一件事情很奇怪——

如果你对一件事情很无力,无力到作者根本不理这个需求,无力到你只能抱怨的时候,我说一句“你抱怨也没用”,有问题么?

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
6 [报告]
发表于 2012-10-09 19:00 |显示全部楼层
回复 15# OwnWaterloo


    好吧,我去加clojure的邮件列表,找一下他们的wiki,争取让他们在reference里面提一下……这个可以有——但问题还是一样的——他们如果不加,你依然没有任何办法,网站在人家手上呢,你除了提一下以外,根本做不了别的任何事情——如果是这样,你有啥办法来着……

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
7 [报告]
发表于 2012-10-09 20:37 |显示全部楼层
回复 24# OwnWaterloo


    好吧好吧,我败了。所有用法,只要你用出来了,就是合理的,好吧………………

不过我还是觉得发布的软件,至少也得装个exe的壳儿,哪怕是脚本写的,这方面的事儿我做过不止一次了,还弄出一个自动装Lua到壳儿的办法……有段时间专门写了一个lunamark-standalone,你知道的…………好吧好吧这不是重点………………

至于一晚上……那的确是我的活跃时间啊……不想写代码找个人扯东扯西的放松一下也不行么……

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
8 [报告]
发表于 2012-10-09 20:50 |显示全部楼层
回复 27# OwnWaterloo


    我也没说这个很挫吧?

我自己写两份是因为shell不认bat好不好……

你要是能找出来在cmd/sh下面通用的混合语言我也跟着搞啊……lua邮件列表又一次就是讨论这个话题的说,不过也没什么结果。

所以这样的确是很麻烦啊……混用linux/windows本来就是麻烦事,也不止这个了,你以前吐槽的tty问题,记得么?问题本来就大把的……

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
9 [报告]
发表于 2012-10-09 21:10 |显示全部楼层
回复 29# OwnWaterloo


    这个我倒是看得懂的………………

对clojure而言:


":" -- 字符串
;  -- 注释

对shell而言:

":"就是escape后的:,空操作
;  命令分隔符,表示两个命令顺次执行

利用的就是这个。

如果觉得可能有问题,可以这样:

:shebang; xxxxxx

我记得冒号后面跟着一个identifier也是空操作的,这个比":"稍微verbose一点。

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
10 [报告]
发表于 2012-10-09 21:27 |显示全部楼层
回复 32# OwnWaterloo


    是这样的,shell命令在实际执行之前,会经过多道处理:

- wildcard替换
- 变量替换
- 脱引号
- 参数分割

等等。

对于:
":"

来说,没有wildcard,没有变量,就走到了脱引号这一步,":"变成了:,而:是builtin-command(内建命令),代表啥也不做。所以最后结果就是啥也不做了~~就是这样~~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP