기능적인 유닉스 쉘이 있습니까?


18

나는 (실제로) 함수형 프로그래밍에 익숙하지 않지만 (실제로는 파이썬을 사용하여 접촉 했음) 쉘 환경에서 목록 집약적 인 작업에 대한 좋은 접근 방법 인 것 같습니다.

나는 이런 식으로하고 싶습니다 :

$ [ git clone $host/$repo for repo in repo1 repo2 repo3 ]

이런 종류의 기능을 가진 유닉스 쉘이 있습니까? 또는 파이썬 내에서 쉽게 쉘 액세스 (명령, env / vars, readline 등)를 허용하는 기능 (파이썬의 대화 형 인터프리터를 bash 대신 사용하는 것이 좋습니다).

편집하다:

아마도 비교 예가 명확해질 것입니다. dir / file 로 구성된 목록이 있다고 가정 해 봅시다 .

$ FILES=( build/project.rpm build/project.src.rpm )

그리고 나는 정말 간단한 작업을하고 싶습니다 : 모든 파일을 dist /에 복사 하고 시스템에 설치하십시오 (빌드 프로세스의 일부입니다).

bash 사용 :

$ cp $ {파일 [*]} dist /
$ cd dist && rpm -Uvh $ ($ {files [*]}에서 f의 경우 : 기본 이름 $ f; done))

"pythonic shell"접근 방식 사용 (주의 : 이것은 가상 코드 임) :

$ cp [파일의 파일에 대한 os.path.join ( 'dist', os.path.basename (file))] 'dist'

당신은 차이점을 볼 수 있습니까? 그것이 내가 말하는 것입니다. 이런 종류의 것들이 내장 된 쉘을 어떻게 종료 할 수 없습니까? 쉘에서 목록을 처리하는 것은 정말 고통 스럽습니다. 파일 목록, PID 목록, 모든 목록 등 매우 일반적인 작업이기도합니다.

그리고 정말 중요한 점은 구문과 도구 / 기능을 사용하는 것입니다. 모두 이미 알고 있습니다 : sh와 python.

IPython은 좋은 방향으로 이음새가 있지만 부풀어 오른다 : var name이 '$'로 시작하면 '$$'이면 그렇게합니다. 구문은 "자연스럽지"않으므로 많은 규칙과 "해결 방법"( [ ln.upper() for ln in !ls ] -> 구문 오류)




4
함수형 프로그래밍에 대한 목록 이해 이상의 것이 있습니다. 주요 초점이 기능 코드를 작성하는 경우 파이썬을 예로 들지 않습니다.
pqnet

답변:


10

있다 계획 쉘 매우 가까이 당신이 찾고있는 무엇을 아마. 나는 그것을 직접 사용하지 않았습니다.

업데이트 :

방금 설치하고 직접 시도했습니다. scsh는 실제로 유용한 대화식 쉘보다 대화식 스키마 해석기 및 스크립팅 언어에 가깝습니다. 당신은 입력 할 수 없습니다

echo hello

문법은

(run (echo hello))

그걸 찾기 위해 몇 분 정도 인터넷 검색이 걸렸습니다. 첫 번째 예 여기에 있습니다 :

gunzip < paper.tex.gz | detex | spell | lpr -Ppulp &

이것은 다음과 같이 번역됩니다.

(& (| (gunzip) (detex) (spell) (lpr -Ppulp)) (< paper.tex.gz))

그러나 간단한 쉘 명령 을 실행하는 방법을 알려주지는 않습니다 .

이 FAQ 항목 은 다음과 같습니다.

4.6 scsh를 대화식 쉘로 사용할 수 있습니까?

기술적으로는 다음과 같이 할 수 있습니다. "scsh"명령을 실행하면 사용 가능한 모든 scsh 기능과 함께 Scheme 48 세션에 들어갑니다. 그러나 이것은 대화식 작업에는 적합하지 않습니다. 명령 줄 편집, 명령 줄 기록, 파일 / 함수 이름 완성, 간결한 구문 등이 없습니다.

이러한 문제를 해결하기 위해 Martin Gasbichler와 Eric Knauel은 scsh 위에서 실행되며 편안한 대화식 환경을 제공하는 Commander S를 작성했습니다. 새로운 기능 중 하나는 많은 Unix 명령의 출력을 이해할 수 있으며 사용자가 유용한 방법으로 탐색하고 조작 할 수 있다는 것입니다. : 사령관 S에 대한 자세한 내용은 기술 한 논문에서 찾을 수 있습니다 http://www.deinprogramm.de/scheme-2005/05-knauel/05-knauel.pdf을 사령관 S를 구하여 설치하는 방법에 대한 지침은에서 사용할 수있는 scsh 웹 사이트 : http://www.scsh.net/resources/commander-s.html

아마 그게 진짜 답일 것입니다.


7

질문에 직접 대답하는 범주에는 Bash 및 Zsh 등의 기능 대체를위한 ES 셸 이 있습니다.

두 번째로,보다 기능적인 표준 쉘 작성을 돕는 범주에서 파이프 밀 기술 학습을 고려하십시오.

who | while read username 
do
  cat <<EOF | grep $username
nic
mark
norman
keith
EOF
done | while read username
do
  echo "you have an answer on superuser.com" | mail -s "well done" $username
done

첫 번째 while 루프는 기능적이며 (루프 keep에서 나오는 널이 아닌 값만 전달) 두 번째는 each(부작용에 대한 맵)입니다.

이것은 쉘에서 fp를 크게 향상시킵니다.

쉘에서 더 많은 fp 스타일로 많은 것을 표현하는 것이 가능하지만, 쉽지 않을 수도 있습니다. 우리 모두가 그렇게 많이 사용하더라도 더 나은 껍질을 만드는 데 관심이없는 것 같습니다.


6

표준 Bourne의 스타일 쉘 ( sh, bash, ksh, 등)은 이미 당신이 할 수 있습니다 :

for repo in repo1 repo2 repo3 ; do git clone $host/$repo ; done

( do및 앞에 세미콜론이 필요합니다 done.) 또한 명령에서 한 번만 나타나는 bash쉘과 다른 쉘에서는 다음과 같이 $repo쓸 수 있습니다.

git clone $host/{repo1,repo2,repo3}

그리고 나는 그것을 많이 사용합니다. 그러나 람다 함수와 같은 다른 것들은 어떻습니까?

8
git clone $host/{repo1,repo2,repo3}for루프 와 같은 일을하지 않습니다 . git clone세 개의 인수로 한 번 호출합니다 . 본질적으로 동일한 일을하는 사실은 git clone작동 방식 의 인공물입니다 . 반드시 다른 명령에는 적용되지 않습니다. (비교 echo foo bar bazecho foo; echo bar; echo baz예를 들어,.)
키이스 톰슨에게

@caruccio 다음 FUN=eval 'git clone '"$host"'$0 과 같이 사용할 람다를 정의하는 데 사용할 수 있습니다for repo in repo{1,2,3} ; do $FUN $repo ; done
pqnet

가장 큰 문제는 유닉스 도구가 종종 파일에 쓰는 것과 같은 부작용이 있으므로 기능적 언어로하고 싶은 것처럼 구성 할 수 없다는 것입니다.
weberc2

2

Scheme Shell, scsh는 정말 좋습니다.

Keith Thompson이 지적했듯이, 그것은 Commander S가 흥미로운 실험처럼 보이지만 대화식 쉘로는 유용하지 않습니다. 대신, 모든 POSIX 바인딩을 사용하는 것이 유용한 상황에 적합한 우수한 프로그래밍 언어입니다. 여기에는 다른 유닉스 응용 프로그램을 호출하려는 경우가 포함됩니다. 수십 줄 이상의 쉘 스크립트는 아무리 깔끔하게 작성하든 항상 해킹처럼 느껴질 것입니다 sh. 대조적으로 scsh를 사용하여 중요한 프로그램을 작성하는 것을 멈추지 않습니다.

scsh는 매우 간결하지는 않지만 (간호 함은 sh- 가족 언어의 강점과 약점 둘 다) 강력합니다.

작고 큰 작업에 유용하고 실용적이기 때문에 scsh는 우연히 Scheme을 파악하는 좋은 방법입니다 (그러나 이것이 목표가 되었더라도 요즘에는 Racket으로 바로 갈 수 있습니다).

기능적 언어의 장점은 목록 집약적 작업에만 국한된 것이 아니라 (역사 때문에 목록을 데이터 구조로 선호하는 경향이 있음)-올바른 언어를 마시면 프로그램을 작성할 수있는 강력한 방법입니다. 도움.

sh 스타일 쉘이 작동한다는 의미는 없으며 파이썬은 람다 기능이 있다는 한계 적 의미에서만 작동합니다.


2

쉘은 필연적으로 표현력이 뛰어나므로 줄, 토큰 등이 적어 많은 것을 달성 할 수 있습니다.

우리는 일반적으로 R, 메이플 등과 같은 쉘 또는 DSL과 같은 특수 목적을 위해 언어를 표현함으로써 언어를 표현합니다. 그리고 C, C ++, Java 등과 같은 대부분의 범용 언어에서는 표현력이 상대적으로 적습니다.

Python, Perl, Ruby 등은 쉘, 알라 오리 타이핑과 유사한 방식으로 표현력이 높은 범용 언어입니다. DSL이는 람, 그들에 용접 얻을 그래서 세이지 수학에 대한. 그러나 실제 쉘 명령에는 그렇게 좋지 않습니다 .

스키마는 모든 괄호로 인해 DLS를 작성한 후에도 표현력이 뛰어납니다.

그러나 Haskell과 같은 기능적 언어는 엄청난 표현력과 DSL 구축 능력이 뛰어납니다. Haskell에 쉘을 만들기위한 흥미로운 노력은 거북껍질 입니다.

실제로 Haskell의 강력하지만 제한적인 유형 시스템으로 인해 노력 도구가 포함 된 학습 곡선이 있지만 상당한 가능성을 보여줍니다.


1

첫째, 당신은 "${files[@]}"당신이 가진 모든 곳에서 사용해야합니다 ${files[*]}. 그렇지 않으면 공백이 엉망이됩니다.

껍질은 이미 꽤 기능적입니다. 텍스트 출력의 관점에서 줄 목록, grepis filter, xargsis map등을 생각하면 파이프는 매우 기능적입니다.

쉘은 가장 친숙한 프로그래밍 환경은 아니지만 Python보다 대화식 사용에 훨씬 적합합니다. 그리고 API와 UI가 동일하다는 매우 좋은 기능을 가지고 있습니다. 한 번에 모두 배우십시오.

왜 당신이 cp [ os.path.join('dist', os.path.basename(file)) for file in FILES ] 'dist'선호 하는지 이해가되지 않습니다 cp "${FILES[@]}" dist. 후자는 타이핑이 훨씬 적습니다.


0

그것이 "기능적" 이라는 것을 모르지만 , scsh 논문이 언급 한 rc 도 있습니다 . es의 전임자입니다.

리눅스 민트 (그리고 아마도 데비안, 우분투 ...)에서 그것을 시도 할 수 있습니다

sudo apt-get install rc
man rc
rc
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.