Linux下的sort命令,在终端执行和在sh文件中执行不一样?

sh/bash/dash/ksh/zsh等Shell脚本
回复
ljyls
帖子: 22
注册时间: 2020-04-22 15:52
系统: Ubuntu 20.04.1 LTS

Linux下的sort命令,在终端执行和在sh文件中执行不一样?

#1

帖子 ljyls » 2020-04-22 15:54

一直以为,终端执行命令和把同一个命令放入sh文件执行是一样的。但是今天用sort命令发现不一样。下面这样一个数据,我以TPM(第4个制表符)那列数字排倒序,终端输入“sort -n -r -k 4 -t $'\t' quant.sf -o sort_quant.sf”能正常运行,但是我把这句放入sh文件执行,会报错sort: multi-character tab ‘$\\t’,好奇怪。有遇到的吗?该如何解决呀?系统是Ubuntu18.04.4 LTS。
Name Length EffectiveLength TPM NumReads
g0_i0 19006 18838.220 4.650770 5986.843
g1_i0 18641 18473.220 0.581840 734.479
g0_i1 18485 18317.220 5.886511 7368.017
g2_i0 17127 16959.220 4.993031 5786.331
g3_i0 16700 16532.220 3.778106 4268.138
g1_i1 16642 16474.220 2.770495 3118.857
g4_i0 16595 16427.220 0.399614 448.578
头像
astolia
论坛版主
帖子: 6514
注册时间: 2008-09-18 13:11

Re: Linux下的sort命令,在终端执行和在sh文件中执行不一样?

#2

帖子 astolia » 2020-04-22 16:06

我猜你在脚本里写的shebang是#!/bin/sh
现在ubuntu里/bin/sh是指向的dash,不是终端里的bash。两个shell是不同的

代码: 全选

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Aug 18  2018 /bin/sh -> dash
你把#!/bin/sh改成#!/bin/bash就好了
ljyls
帖子: 22
注册时间: 2020-04-22 15:52
系统: Ubuntu 20.04.1 LTS

Re: Linux下的sort命令,在终端执行和在sh文件中执行不一样?

#3

帖子 ljyls » 2020-04-22 16:08

astolia 写了: 2020-04-22 16:06 我猜你在脚本里写的shebang是#!/bin/sh
现在ubuntu里/bin/sh是指向的dash,不是终端里的bash,两个shell是不同的

代码: 全选

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Aug 18  2018 /bin/sh -> dash
你把#!/bin/sh改成#!/bin/bash就行了
用的是#!/bin/bash噢
头像
astolia
论坛版主
帖子: 6514
注册时间: 2008-09-18 13:11

Re: Linux下的sort命令,在终端执行和在sh文件中执行不一样?

#4

帖子 astolia » 2020-04-22 16:12

那你是不是用sh xxx.sh这样来运行的呢?这样还是在用dash来执行的哦
两个shell写制表符的语法是不同的,dash里直接'\t'就行
ljyls
帖子: 22
注册时间: 2020-04-22 15:52
系统: Ubuntu 20.04.1 LTS

Re: Linux下的sort命令,在终端执行和在sh文件中执行不一样?

#5

帖子 ljyls » 2020-04-23 11:36

astolia 写了: 2020-04-22 16:12 那你是不是用sh xxx.sh这样来运行的呢?这样还是在用dash来执行的哦
两个shell写制表符的语法是不同的,dash里直接'\t'就行
测试了以下情况的各种组合:sh xxx.sh,bash xxx.sh,脚本文件#!/bin/sh,脚本文件#!/bin/bash,脚本文件$'\t',脚本文件'\t'。有且仅有bash xxx.sh + 脚本文件#!/bin/bash + $'\t'可以运行成功。多谢提供思路。看来以后必须改成bash xxx.sh + 脚本文件#!/bin/bash的方式运行了,这样才和在终端一步步执行命令效果一致。再次感谢!
头像
astolia
论坛版主
帖子: 6514
注册时间: 2008-09-18 13:11

Re: Linux下的sort命令,在终端执行和在sh文件中执行不一样?

#6

帖子 astolia » 2020-04-23 15:23

astolia 写了: 2020-04-22 16:12 dash里直接'\t'就行
我这里说错了,dash内置的echo命令能直接把'\t'解析为制表符,其他情况还是不认。
ljyls 写了: 2020-04-23 11:36 测试了以下情况的各种组合:sh xxx.sh,bash xxx.sh,脚本文件#!/bin/sh,脚本文件#!/bin/bash,脚本文件$'\t',脚本文件'\t'。有且仅有bash xxx.sh + 脚本文件#!/bin/bash + $'\t'可以运行成功。多谢提供思路。看来以后必须改成bash xxx.sh + 脚本文件#!/bin/bash的方式运行了,这样才和在终端一步步执行命令效果一致。再次感谢!
把基础知识弄清楚就用不着排列组合一个个试了。而且你的结论也有点问题
1、首先是/bin/sh,代表系统的默认shell,各个系统上这个可能不同。在现在的ubuntu上,它是dash。如果你选择使用/bin/sh,那么在脚本编写上只能选择通用语法,用到各个shell特有的语法时就可能出问题。
2、$'\t'是bash特有的语法,其他shell不一定支持相同语法。制表符的通用写法,就是单纯的制表符,dash里可以直接按tab输入,bash里要按ctrl+v后再按tab输入。记得用引号包裹。
3、shell xxx.sh这种运行方式,由于shebang是以#开头,所以整行会被当成注释忽略掉。所以你选择的shell是什么就用什么执行,shebang完全不影响。
4、shebang的用处在于,当你给xxx.sh加上可执行权限后,以./xxx.sh这类形式直接运行时,系统会根据shebang自动调用相应的shell来执行。这个特性也不局限于shell,任意一种脚本语言都可以。
5、如果脚本里不写shebang,在终端里./xxx.sh的执行效果就和直接在终端使用的shell里逐行输入效果一致
6、终端程序里的shell,默认是bash。

综上,如果你想确保原来的脚本和终端里直接输入的运行效果一致,要么采用bash xxx.sh的方式运行,要么以./xxx.sh的方式运行。如果是想让脚本能在不同shell里都能运行,那么最好把$'\t'改成

代码: 全选

'	'
ljyls
帖子: 22
注册时间: 2020-04-22 15:52
系统: Ubuntu 20.04.1 LTS

Re: Linux下的sort命令,在终端执行和在sh文件中执行不一样?

#7

帖子 ljyls » 2020-08-04 10:20

astolia 写了: 2020-04-23 15:23
astolia 写了: 2020-04-22 16:12 dash里直接'\t'就行
我这里说错了,dash内置的echo命令能直接把'\t'解析为制表符,其他情况还是不认。
ljyls 写了: 2020-04-23 11:36 测试了以下情况的各种组合:sh xxx.sh,bash xxx.sh,脚本文件#!/bin/sh,脚本文件#!/bin/bash,脚本文件$'\t',脚本文件'\t'。有且仅有bash xxx.sh + 脚本文件#!/bin/bash + $'\t'可以运行成功。多谢提供思路。看来以后必须改成bash xxx.sh + 脚本文件#!/bin/bash的方式运行了,这样才和在终端一步步执行命令效果一致。再次感谢!
把基础知识弄清楚就用不着排列组合一个个试了。而且你的结论也有点问题
1、首先是/bin/sh,代表系统的默认shell,各个系统上这个可能不同。在现在的ubuntu上,它是dash。如果你选择使用/bin/sh,那么在脚本编写上只能选择通用语法,用到各个shell特有的语法时就可能出问题。
2、$'\t'是bash特有的语法,其他shell不一定支持相同语法。制表符的通用写法,就是单纯的制表符,dash里可以直接按tab输入,bash里要按ctrl+v后再按tab输入。记得用引号包裹。
3、shell xxx.sh这种运行方式,由于shebang是以#开头,所以整行会被当成注释忽略掉。所以你选择的shell是什么就用什么执行,shebang完全不影响。
4、shebang的用处在于,当你给xxx.sh加上可执行权限后,以./xxx.sh这类形式直接运行时,系统会根据shebang自动调用相应的shell来执行。这个特性也不局限于shell,任意一种脚本语言都可以。
5、如果脚本里不写shebang,在终端里./xxx.sh的执行效果就和直接在终端使用的shell里逐行输入效果一致
6、终端程序里的shell,默认是bash。

综上,如果你想确保原来的脚本和终端里直接输入的运行效果一致,要么采用bash xxx.sh的方式运行,要么以./xxx.sh的方式运行。如果是想让脚本能在不同shell里都能运行,那么最好把$'\t'改成

代码: 全选

'	'
收到,谢谢
回复