매개 변수를 사용하는 Bash 별칭을 만드시겠습니까?


1270

나는 CShell을 사용했다.)를 사용하면 매개 변수를 사용하는 별칭을 만들 수 있습니다. 표기법은

alias junk="mv \\!* ~/.Trash"

Bash에서는 이것이 작동하지 않는 것 같습니다. Bash에 유용한 기능이 많이 있다고 가정하면이 기능이 구현되었다고 가정하지만 어떻게 궁금합니다.



2
인수 주위에 따옴표를 사용해야합니다"$1"
Christophe Roussy

이 질문은 SO에 대한 주제가 아닙니다. 그것은 한 UNIX.SE에 대답 , 대답은 당신도 귀찮게 할 필요가 없다는 것입니다 : "당신이 별명 인 경우, 예를 들어 lsls -la, 다음 타자는 ls foo bar정말 실행합니다 ls -la foo bar. 명령 줄에"
Dan Dascalescu

7
문자열 중간에 변수를 보간하는 데 도움이되지 않습니다.
Franz Sittampalam

1
여기에 릴 테스트 나는이 착오를 검색하는 데 사용 별명을의 ... alias test_args="echo PREFIX --$1-- SUFFIX", 어떤 호출 할 때 test_args ABCD수율 다음과 같은 콘솔 출력PREFIX ---- SUFFIX ABCD
jxramos

답변:


2122

Bash 별명은 매개 변수를 직접 승인하지 않습니다. 함수를 만들어야합니다.

alias매개 변수를 허용하지 않지만 별명처럼 함수를 호출 할 수 있습니다. 예를 들면 다음과 같습니다.

myfunction() {
    #do things with parameters like $1 such as
    mv "$1" "$1.bak"
    cp "$2" "$1"
}


myfunction old.conf new.conf #calls `myfunction`

그건 그렇고, 당신 .bashrc과 다른 파일에 정의 된 Bash 함수 는 쉘 내에서 명령으로 사용할 수 있습니다. 예를 들어 다음과 같이 이전 함수를 호출 할 수 있습니다.

$ myfunction original.conf my.conf

48
나는 포장해야 $1따옴표로?
Jürgen Paul

263
별명을 선언 할 필요조차 없습니다. 기능을 정의하면됩니다.
dinigo

206
별명을 함수로 변경하는 경우 source.bashrc를 사용하면 함수가 추가되지만 이전 별명은 별명으로 지정되지 않습니다. 별명은 함수보다 우선 순위가 높으므로 별명을 사용하려고합니다. 쉘을 닫았다가 다시 열거 나을 호출해야 unalias <name>합니다. 아마도 내가 방금 낭비한 5 분을 누군가를 구할 것입니다.
Marty Neal

55
@MartinNeal : Sun에서 배운 한 가지 시간 절약 요령은 exec bash다음과 같습니다. 새 쉘을 시작하여 마치 마치 닫았다가 다시 열린 것처럼 구성을 깨끗하게 읽을 수 있지만 해당 세션의 환경 변수 설정도 유지합니다 . 또한 bashexec없이 실행 하면 스택처럼 생각을 처리 할 때 유용 할 수 있습니다.
Macneil Shonle

21
@mich-예, 항상 bash 변수를 따옴표로 묶으십시오. 예 mv "$1" "$1.bak". 따옴표없이 $ 1이 "hello world"인 경우 mv hello world hello world.bak대신 실행 합니다 mv "hello world" "hello world.bak".
오리온 엘렌 질

208

위의 답변을 수정하면 별칭과 마찬가지로 1 줄 구문을 얻을 수 있습니다. 이는 쉘 또는 .bashrc 파일의 임시 정의에 더 편리합니다.

bash$ myfunction() { mv "$1" "$1.bak" && cp -i "$2" "$1"; }

bash$ myfunction original.conf my.conf

오른쪽 대괄호를 닫기 전에 세미콜론을 잊지 마십시오. 마찬가지로 실제 질문에 대해 :

csh% alias junk="mv \\!* ~/.Trash"

bash$ junk() { mv "$@" ~/.Trash/; }

또는:

bash$ junk() { for item in "$@" ; do echo "Trashing: $item" ; mv "$item" ~/.Trash/; done; }

3
나는이 답변을 선호합니다. 이것은 들어오는 인수 배열을 반복하는 것을 보여줍니다. $ 1과 $ 2는 특별한 경우이며,이 답변에도 나와 있습니다.
philo vivero

16
변경 mv "$1" "$1.bak"; cp "$2" "$1" 으로 mv "$1" "$1.bak" && cp "$2" "$1"당신의 데이터가 손실되지에 때 mv문제로 실행 (예를 들어, 파일 시스템 전체).
Henk Langeveld

3
"닫기 오른쪽 대괄호 앞에 세미콜론을 잊지 마십시오." 여러 번이! 감사합니다 :)
Kaushal Modi

그리고 첫 번째 대괄호 뒤와 마지막 대괄호 앞의 공백도 필요합니다.
Bryan Chapel

1
@HenkLangeveld 당신의 말이 완벽하게 맞았지만 당신이 한동안 주변에 있었다는 것을 보여줍니다.- "장치에 남은 공간이 없습니다"라는 오류가 마지막으로 언제 발생했는지는 알 수 없습니다 ;-). (키친 카운터에서 더 이상 공간을 찾지 못하면 정기적으로 사용합니다!) 요즘에는 자주 발생하지 않는 것 같습니다.
피터-모니카 복원 복원

124

질문은 단순히 잘못 요청됩니다. alias이미 존재하는 것에 대한 두 번째 이름 만 추가 하기 때문에 매개 변수를 사용하는 별칭을 만들지 않습니다 . OP가 원하는 기능은 function새 기능을 만드는 명령입니다. 함수에 이미 이름이 있으므로 함수의 별명을 지정할 필요가 없습니다.

나는 당신이 이와 같은 것을 원한다고 생각합니다 :

function trash() { mv "$@" ~/.Trash; }

그게 다야! 매개 변수 $ 1, $ 2, $ 3 등을 사용하거나 $ @로 모두 채울 수 있습니다.


7
이 답변은 모든 것을 말합니다. 이 페이지 하단에서 읽으면 시간을 절약했을 것입니다.
joe

-1 별명과 함수는 동일하지 않습니다 ...echo -e '#!/bin/bash\nshopt -s expand_aliases\nalias asrc='\''echo "${BASH_SOURCE[0]}"'\'' # note the '\''s\nfunction fsrc(){ echo "${BASH_SOURCE[0]}";}'>>file2&&echo -e '#!/bin/bash\n. file2\nalias rl='\''readlink -f'\''\nrl $(asrc)\nrl $(fsrc)'>>file1&&chmod +x file1&&./file1;rm -f file1 file2
Fuzzy Logic

$@공백 등을 포함한 파일 이름을 지원 하려면 인용해야합니다 .
Tom Hale

별칭 매개 변수가 없다는 일반적인 설명으로 대신 함수를 사용합니다. 주어진 함수는 원래 예제와 반대되는 예제 일뿐입니다. 나는 그 사람이 범용 쓰레기 기능을 찾고 있다고 생각하지 않습니다. 그러나 더 나은 코드를 제공하기 위해 답변을 업데이트했습니다.
Evan Langlois 5

1
@FuzzyLogic-귀하의 의견에 코드를 풀려고 몇 분을 보냈습니다. 그것은 코드를 올바르게 포맷 할 수없는 주석에 일부 코드를 포장하기 위해 많은 (흥미로운) 노력입니다. 나는 아직도 그것이 무엇을하는지, 더 중요한 것은 그것이 왜 당신의 (올바른) 주장을지지하는지 이해하지 못했습니다.
Joe

110

TL; DR : 대신이 작업을 수행하십시오

별명보다 함수를 사용하여 명령 중간에 인수를 넣는 것이 훨씬 쉽고 읽기 쉽습니다.

$ wrap_args() { echo "before $@ after"; }
$ wrap_args 1 2 3
before 1 2 3 after

계속 읽으면 쉘 인수 처리에 대해 알 필요가없는 것들을 배우게됩니다. 지식은 위험합니다. 어두운면이 운명을 영원히 지배하기 전에 원하는 결과를 얻으십시오.

설명

bash별명 인수를 허용하지만 끝에 만 허용됩니다 .

$ alias speak=echo
$ speak hello world
hello world

명령 비아 의 중간 에 인수를 넣는 alias것은 실제로 가능하지만 추악합니다.

집에서 이것을 시도하지 마십시오, 꼬마!

한계를 우회하고 다른 사람들의 말을하는 것이 불가능하다면, 여기에 레시피가 있습니다. 머리카락이 흐트러지고 얼굴이 그을음 미친 과학자 스타일로 덮힌다면 나를 비난하지 마십시오.

해결 방법은 alias끝에 만 허용 되는 인수를 중간에 삽입 한 다음 명령을 실행하는 랩퍼로 전달하는 것입니다.

해결책 1

실제로 함수 자체를 사용하지 않으면 다음을 사용할 수 있습니다.

$ alias wrap_args='f(){ echo before "$@" after;  unset -f f; }; f'
$ wrap_args x y z
before x y z after

당신은 대체 할 수 $@와 함께 $1당신은 단지 첫 번째 인수를 원하는 경우.

설명 1

이것은 임시 함수를 만들어 f인수를 전달합니다 ( f최후에 호출 됨). 이 unset -f별칭은 별칭이 실행될 때 함수 정의를 제거하므로 나중에 중단되지 않습니다.

해결책 2

서브 쉘을 사용할 수도 있습니다.

$ alias wrap_args='sh -c '\''echo before "$@" after'\'' _'

설명 2

별명은 다음과 같은 명령을 작성합니다.

sh -c 'echo before "$@" after' _

코멘트:

  • 자리 표시자가 _필요하지만 아무 것도 될 수 있습니다. 그것은으로 설정됩니다 sh의 ' $0, 및 사용자 지정된 인수의 첫 번째가 소모되지 않도록해야합니다. 데모:

    sh -c 'echo Consumed: "$0" Printing: "$@"' alcohol drunken babble
    Consumed: alcohol Printing: drunken babble
  • 작은 따옴표 안에 작은 따옴표가 필요합니다. 큰 따옴표로 작동하지 않는 예는 다음과 같습니다.

    $ sh -c "echo Consumed: $0 Printing: $@" alcohol drunken babble
    Consumed: -bash Printing:

    다음은 대화 형 쉘의 값 $0과는 $@인용 더블로 교체 하기 전에 이 전달됩니다 sh. 증거는 다음과 같습니다.

    echo "Consumed: $0 Printing: $@"
    Consumed: -bash Printing:

    작은 따옴표는 이러한 변수가 대화식 쉘에 의해 해석되지 않고 문자 그대로로 전달되도록 sh -c합니다.

    큰 따옴표와을 사용할 수 \$@있지만 가장 좋은 방법은 공백을 포함 할 수 있으므로 인수를 인용하고 \"\$@\"더 나쁘게 보이지만 모발이 모발에 들어가기위한 난독 화 컨테스트에서이기는 데 도움이 될 수 있습니다.


2
해결 방법 1의 경우 작은 따옴표를 사용하고 $ @ 주위에 \ "를 사용하지
않아야

솔루션 1은 원하는 각 서버에 대한 인수로 rdesktop-vrdp를 래핑했습니다.
Hsehdar

마지막에 인수를 수락하는 것은 "git checkout {branchname}"을 간단한 "gc {branchname}"으로 바꾸는 데 필요한 것입니다. .bash_profile에서 간단히 추가해야했습니다alias gc='git checkout'
AbstractVoid

@ sgtz 왜 따옴표를 제거하고 싶 $@습니까? 예를 들어 공백이있는 파일이있는 경우 필요합니다.
Tom Hale

@TomHale 이것은 다소 언어학이지만 솔루션 1은 함수 정의를 실행 시간으로 만 전환한다는 사실을 직접 인정했기 때문에 누군가가 함수 사용에 반대하는 경우 실제로 유용하지 않습니다 (이유가 무엇이든간에) 별명. 두 번째로 "bash 별명은 인수를 허용하지만 끝에 만"이 더 의미가 있습니다. 별명은 정의에 따라 단어를 문자열로 대체합니다. 그러나 인수를 받아 들일 필요는 없지만 대체를 통해 실행되는 명령은 가능합니다. 별명은 더 이상 아무것도 아닌 문자 교체입니다. 아니?
BUFU

39

다른 해결책은 최근에 만든 도구 인 marker 를 사용 하여 명령 템플릿을 "책갈피"하고 커서를 명령 자리 표시 자에 쉽게 배치 할 수 있습니다.

커맨드 라인 마커

대부분의 경우 쉘 함수를 사용하므로 자주 사용하는 명령을 명령 줄에 반복해서 쓸 필요가 없습니다. 이 사용 사례에 함수를 사용하는 문제는 명령 어휘에 새로운 용어를 추가하고 실제 명령에서 함수 매개 변수가 무엇을 참조하는지 기억해야합니다. 마커 목표는 그 정신적 부담을 제거하는 것입니다.


14

별명 안에 함수를 작성하기 만하면됩니다.

$ alias mkcd='_mkcd(){ mkdir "$1"; cd "$1";}; _mkcd'

당신은 있어야 하기 때문에 작은 따옴표는하지 않습니다 일을 "$ 1"주위에 따옴표를 넣어.


5
그것은 영리하지만 질문이 별칭을 만들기 위해 지정한 사실 외에는 처음에 별칭과 이름이 같은 함수를 만들지 않는 이유가 있습니까?
xaxxon

1
@xaxxon 실제로는 아니지만 함수가 아닌 별칭을 사용하는 가장 쉬운 방법입니다.
Ken Tran

1
작동하지 않습니다. 우분투 18에서 오류가 발생했습니다 bash: syntax error near unexpected token '{mkdir'.
Shital Shah

;함수 내부 에 후행이 누락 _mkcd되면 오류가 발생했을 가능성이 큽니다.
Jetchisel

전후 공간을 확보 {하고}
hesham_EE

10

여기 내 함수의 세 가지 예가 ~/.bashrc있습니다. 기본적 으로 매개 변수를 허용하는 별칭입니다.

#Utility required by all below functions.
#/programming/369758/how-to-trim-whitespace-from-bash-variable#comment21953456_3232433
alias trim="sed -e 's/^[[:space:]]*//g' -e 's/[[:space:]]*\$//g'"

.

:<<COMMENT
    Alias function for recursive deletion, with are-you-sure prompt.

    Example:
        srf /home/myusername/django_files/rest_tutorial/rest_venv/

    Parameter is required, and must be at least one non-whitespace character.

    Short description: Stored in SRF_DESC

    With the following setting, this is *not* added to the history:
        export HISTIGNORE="*rm -r*:srf *"
    - https://superuser.com/questions/232885/can-you-share-wisdom-on-using-histignore-in-bash

    See:
    - y/n prompt: https://stackoverflow.com/a/3232082/2736496
    - Alias w/param: https://stackoverflow.com/a/7131683/2736496
COMMENT
#SRF_DESC: For "aliaf" command (with an 'f'). Must end with a newline.
SRF_DESC="srf [path]: Recursive deletion, with y/n prompt\n"
srf()  {
    #Exit if no parameter is provided (if it's the empty string)
        param=$(echo "$1" | trim)
        echo "$param"
        if [ -z "$param" ]  #http://tldp.org/LDP/abs/html/comparison-ops.html
        then
          echo "Required parameter missing. Cancelled"; return
        fi

    #Actual line-breaks required in order to expand the variable.
    #- https://stackoverflow.com/a/4296147/2736496
    read -r -p "About to
    sudo rm -rf \"$param\"
Are you sure? [y/N] " response
    response=${response,,}    # tolower
    if [[ $response =~ ^(yes|y)$ ]]
    then
        sudo rm -rf "$param"
    else
        echo "Cancelled."
    fi
}

.

:<<COMMENT
    Delete item from history based on its line number. No prompt.

    Short description: Stored in HX_DESC

    Examples
        hx 112
        hx 3

    See:
    - https://unix.stackexchange.com/questions/57924/how-to-delete-commands-in-history-matching-a-given-string
COMMENT
#HX_DESC: For "aliaf" command (with an 'f'). Must end with a newline.
HX_DESC="hx [linenum]: Delete history item at line number\n"
hx()  {
    history -d "$1"
}

.

:<<COMMENT
    Deletes all lines from the history that match a search string, with a
    prompt. The history file is then reloaded into memory.

    Short description: Stored in HXF_DESC

    Examples
        hxf "rm -rf"
        hxf ^source

    Parameter is required, and must be at least one non-whitespace character.

    With the following setting, this is *not* added to the history:
        export HISTIGNORE="*hxf *"
    - https://superuser.com/questions/232885/can-you-share-wisdom-on-using-histignore-in-bash

    See:
    - https://unix.stackexchange.com/questions/57924/how-to-delete-commands-in-history-matching-a-given-string
COMMENT
#HXF_DESC: For "aliaf" command (with an 'f'). Must end with a newline.
HXF_DESC="hxf [searchterm]: Delete all history items matching search term, with y/n prompt\n"
hxf()  {
    #Exit if no parameter is provided (if it's the empty string)
        param=$(echo "$1" | trim)
        echo "$param"
        if [ -z "$param" ]  #http://tldp.org/LDP/abs/html/comparison-ops.html
        then
          echo "Required parameter missing. Cancelled"; return
        fi

    read -r -p "About to delete all items from history that match \"$param\". Are you sure? [y/N] " response
    response=${response,,}    # tolower
    if [[ $response =~ ^(yes|y)$ ]]
    then
        #Delete all matched items from the file, and duplicate it to a temp
        #location.
        grep -v "$param" "$HISTFILE" > /tmp/history

        #Clear all items in the current sessions history (in memory). This
        #empties out $HISTFILE.
        history -c

        #Overwrite the actual history file with the temp one.
        mv /tmp/history "$HISTFILE"

        #Now reload it.
        history -r "$HISTFILE"     #Alternative: exec bash
    else
        echo "Cancelled."
    fi
}

참고 문헌 :


응? 이것은 별칭이 아닌 함수입니다. 그리고 당신의 참고 문헌 중 하나는 바로이 질문입니다.
tripleee

2
아니요, 정확히 기능처럼 작동합니다. 여기에 설명 된 여러 답변과 같이 매개 변수를 사용하는 별칭을 만들 수 없습니다. 당신이 할 수있는 것은 당신이 한 일인 함수를 작성하는 것입니다.
tripleee

1
@tripleee 내 bash 초보자 관점에서 귀하의 의견을 읽기 전에 그것이 별명이라고 생각했습니다 (하나를 만드는 다른 방법). 내가 알 수있는 한 정확하게 기능합니다. 그것은이다 기본적으로 나는 용어에 떨어져어도, 매개 변수를 받아들이는 별명입니다. 문제가 보이지 않습니다. 이 문제에서 다른 답변에 대한 링크를 분명히했습니다. 그것은 이것을 만드는 데 도움이되었습니다.
aliteralmind

1
아마도 이것이 불가능하다는 것을 이해했기 때문에 "매개 변수를 허용하는 bash 별칭"이라는 질문에 구체적으로 대답하지는 않지만 확실히 효과적으로 응답합니다. 내가 여기서 무엇을 놓치고 있습니까?
aliteralmind

2
여기에 정말 좋은 예제와 잘 주석 처리 된 코드가 있습니다. 이 페이지를 찾는 사람들에게 큰 도움이됩니다.
chim

9

배시 별칭은 절대적으로 매개 변수를 허용합니다. 방금 별칭을 추가하여 앱 이름을 매개 변수로 허용하는 새로운 반응 앱을 만들었습니다. 내 과정은 다음과 같습니다.

nano에서 편집 할 bash_profile을 엽니 다

nano /.bash_profile

한 줄에 하나씩 별명을 추가하십시오.

alias gita='git add .'
alias gitc='git commit -m "$@"'
alias gitpom='git push origin master'
alias creact='npx create-react-app "$@"'

참고 : "$ @"은 "creact my-new-app"와 같이 전달 된 매개 변수를 허용합니다.

nano 편집기 저장 및 종료

ctrl + o를 눌러 쓰십시오 (Enter를 누르십시오). 종료하려면 ctrl + x

.bash_profile에서 새 별명을 사용하도록 터미널에 지시하십시오.

source /.bash_profile

그게 다야! 이제 새 별칭을 사용할 수 있습니다


6

NB : 아이디어가 명확하지 않은 경우, 별칭 이외의 다른 별칭을 사용하는 것은 좋지 않습니다. 첫 번째 별칭은 '별칭의 기능'이고 다른 하나는 '리디렉션 / 소스를 읽기 어려운'입니다. 또한 결함 이 있습니다 (명백 하다고 생각 했지만 혼란 스러울 경우를 대비하여 실제로 사용되는 곳은 아닙니다 ...)

.................................................. .................................................. ............................................

나는 이것에 대해 전에 대답했으며 과거에는 항상 이렇게했습니다.

alias foo='__foo() { unset -f $0; echo "arg1 for foo=$1"; }; __foo()'

함수를 함께 사용하지 않는 한 괜찮습니다. 이 경우 텍스트를 리디렉션하는 bash의 방대한 기능을 활용할 수 있습니다.

alias bar='cat <<< '\''echo arg1 for bar=$1'\'' | source /dev/stdin'

그것들은 모두 같은 길이로 몇자를 주거나받습니다.

실제 키커 시간차되면, '기능 방식'과 '리디렉션 소스 "방식 인 바닥 되 가기. 이 이론을 증명하기 위해 타이밍 자체를 말합니다.

arg1 for foo=FOOVALUE
 real 0m0.011s user 0m0.004s sys 0m0.008s  # <--time spent in foo
 real 0m0.000s user 0m0.000s sys 0m0.000s  # <--time spent in bar
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
 real 0m0.010s user 0m0.004s sys 0m0.004s
 real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
 real 0m0.011s user 0m0.000s sys 0m0.012s
 real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
 real 0m0.012s user 0m0.004s sys 0m0.004s
 real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
 real 0m0.010s user 0m0.008s sys 0m0.004s
 real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE

이것은 무작위 간격으로 수행되는 약 200 개의 결과 중 가장 낮은 부분입니다. 함수 생성 / 파괴는 리디렉션보다 시간이 더 걸린 것 같습니다. 잘만되면 이것이이 질문의 미래 방문자에게 도움이 될 것입니다 (나 자신에게 그것을 유지하고 싶지 않았습니다).


2
함수를 정의하는 별칭이 있으면 해당 함수를 실행하는 것은 어리석은 일입니다. 그냥 함수를 작성하십시오. 거의 모든 목적에서 별명은 쉘 기능으로 대체됩니다.
geirha

당신이 시도 할 수있는 모든 것을 읽지 않은 경우에, 나는 왜 함수 방법을 사용하는 것이 처음에는 좋지 않은지를 보여 주었고, 더 이상 어리석지 않습니다. 개인적으로 마음에 들지 않아서 게시 및 게시 중단을 중지하거나 최소한 유효한 설명을 제공하십시오. 이름 호출은 첫 징후 가까이의 마인드입니다 ...
osirisgothra

1
두 번째 것 (막대 별칭)에는 여러 가지 부작용이 있습니다. 먼저이 명령은 stdin을 사용할 수 없습니다. 둘째, 별칭 뒤에 인수가 제공되지 않으면 쉘이 발생하는 인수가 대신 전달됩니다. 기능을 사용하면 이러한 모든 부작용을 피할 수 있습니다. (또한 고양이의 쓸모없는 사용).
geirha

2
야, 나는이 일을하는 것이 좋은 생각이라고 결코 말하지 않았다. 나는 방금 다른 방법이 있다고 말했다. 여기서 주요 아이디어는 복잡한 것보다 느리기 때문에 별칭에서 함수를 사용해서는 안된다는 것이다 리디렉션, 나는이 자명하다 생각하지만 난 (나는 또한 내가 처음에 그것을 한 경우에 너무 비 대한되는 게시물에 대한 호통받을) 모두를 위해 그것을 밖으로 철자가 생각
osirisgothra

1
bar 의 타이밍 이 모두 0 이므로 셸이 올바르게 타이밍하지 않는 것 같습니다. 명령이 실행 되기 전에 시간 메시지가 인쇄 됩니까? Ergo, 그것은 아무 것도 곱한 다음 막대를 수행하므로 막대를 전혀 측정하지 않습니다. 더 복잡하거나 큰 루프 바를 사용하여 아무
Evan Langlois

6

하나 또는 두 개 또는 다른 하드 코딩 된 양이 아닌 함수에 모든 매개 변수를 적용하는 일반적인 방법을 찾고 있다면 다음과 같이 할 수 있습니다.

#!/usr/bin/env bash

# you would want to `source` this file, maybe in your .bash_profile?
function runjar_fn(){
    java -jar myjar.jar "$@";
}

alias runjar=runjar_fn;

위의 예에서, 나는 runjar별칭을 실행할 때부터 모든 매개 변수를 전달합니다 .

예를 들어, 내가 한 경우 runjar hi there실제로 실행 java -jar myjar.jar hi there됩니다. 내가 한 경우 runjar one two three실행 java -jar myjar.jar one two three됩니다.

$@기반 솔루션은 여러 매개 변수와 함께 작동하기 때문에 좋아합니다 .


4
왜 함수 runjar의 별칭 대신 함수의 이름을 지정하지 않습니까? 불필요하게 복잡한 것 같습니다!
Evan Langlois

@EvanLanglois 함수는 bash 파일에서 자동으로 alias(또는 사물의 속성이 전달됨 alias)? 그렇다면, 그 사실은 알지 못했을 것입니다
Micah

무슨 뜻인지 이해하지 마십시오. 별명은 사람이나 기능인 다른 이름입니다. 따라서 함수를 만든 다음 함수의 두 번째 이름을 만들었습니다. 별명에는 특별한 것이 없으며 별명이며 필수는 아닙니다. 명령 행에 입력하는 것은 내부 또는 외부 기능 일 수 있으므로 "기능"은 별명이 아닌 새 명령을 작성합니다.
Evan Langlois

4
이것은 무의미합니다. 와 동일합니다 alias runjar='java -jar myjar.jar'. 별명은 인수를 허용하지만 끝에 만 허용됩니다.
Tom Hale

6

별명 중간에 매개 변수를 삽입 할 수 없다고 말하는 모든 사람들에게 방금 테스트 한 결과 작동한다는 것을 알았습니다.

alias mycommand = "python3"$ 1 "script.py --folderoutput 결과 /"

그런 다음 내 명령 foobar를 실행할 때 명령을 오랫동안 입력 한 것처럼 정확하게 작동했습니다.


물론, alias는 매개 변수를 얻을 수 있습니다. 예를 들어 alias commit = "git commit -m $ 1"
agapitocandemor

나를 위해 작동하지 않습니다 : 나에게 alias myalias="echo 1 "$1" 3"; myalias 2제공 :1 3 2
dirdi

4

임의의 인수를 재배치하는 메커니즘이없는 bash 별명 문제에 대한 일반화 된 솔루션을 원하는 합법적 인 기술적 이유가 있습니다. 한 가지 이유는 실행하려는 명령이 기능 실행으로 인한 환경 변경으로 인해 부정적인 영향을받는 경우입니다. 다른 모든 경우에는 기능을 사용해야합니다.

최근에 이것에 대한 해결책을 시도하도록 강요 한 것은 변수와 함수의 정의를 인쇄하기위한 약식 명령을 만들고 싶었다는 것입니다. 그래서 나는 그 목적을 위해 몇 가지 기능을 썼습니다. 그러나 함수 호출 자체에 의해 변경되거나 변경 될 수있는 특정 변수가 있습니다. 그들 중에는 :

FUNCNAME BASH_SOURCE BASH_LINENO BASH_ARGC BASH_ARGV

변수 defn을 인쇄하기 위해 (함수에서) 사용했던 기본 명령. set 명령의 출력 형식은 다음과 같습니다.

sv () { set | grep --color=never -- "^$1=.*"; }

예 :

> V=voodoo
sv V
V=voodoo

문제점 : 대화식 쉘 프롬프트 (또는 함수 호출이 아닌 경우)에 FUNCNAME이 정의되어 있지 않은 경우, 현재 컨텍스트 에있는 위에서 언급 한 변수의 정의를 인쇄 하지 않습니다. 그러나 내 기능은 잘못된 정보를 알려줍니다.

> sv FUNCNAME
FUNCNAME=([0]="sv")

내가 생각해 낸 한 가지 해결책은이 주제에 대한 다른 게시물에서 다른 사람들에 의해 언급되었습니다. 이 특정 명령이 변수 defn을 인쇄하고 하나의 인수 만 필요로하기 위해 다음과 같이했습니다.

alias asv='(grep -- "^$(cat -)=.*" <(set)) <<<'

올바른 출력 (없음)과 결과 상태 (거짓)를 제공합니다.

> asv FUNCNAME
> echo $?
1

그러나 나는 여전히 임의의 수의 논쟁에 적합한 해결책을 찾아야한다고 느꼈습니다.

임의의 인수를 Bash 별칭 명령에 전달하는 일반적인 솔루션 :

# (I put this code in a file "alias-arg.sh"):

# cmd [arg1 ...] – an experimental command that optionally takes args,
# which are printed as "cmd(arg1 ...)"
#
# Also sets global variable "CMD_DONE" to "true".
#
cmd () { echo "cmd($@)"; declare -g CMD_DONE=true; }

# Now set up an alias "ac2" that passes to cmd two arguments placed
# after the alias, but passes them to cmd with their order reversed:
#
# ac2 cmd_arg2 cmd_arg1 – calls "cmd" as: "cmd cmd_arg1 cmd_arg2"
#
alias ac2='
    # Set up cmd to be execed after f() finishes:
    #
    trap '\''cmd "${CMD_ARGV[1]}" "${CMD_ARGV[0]}"'\'' SIGUSR1;
    #        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    #       (^This is the actually execed command^)
    #
    # f [arg0 arg1 ...] – acquires args and sets up trap to run cmd:
    f () {
        declare -ag CMD_ARGV=("$@");  # array to give args to cmd
        kill -SIGUSR1 $$;             # this causes cmd to be run
        trap SIGUSR1;                 # unset the trap for SIGUSR1
        unset CMD_ARGV;               # clean up env...
        unset f;                      # incl. this function!
    };
    f'  # Finally, exec f, which will receive the args following "ac2".

예 :

> . alias-arg.sh
> ac2 one two
cmd(two one)
>
> # Check to see that command run via trap affects this environment:
> asv CMD_DONE
CMD_DONE=true

이 솔루션의 좋은 점은 명령에 대한 위치 매개 변수 (인수)를 처리하는 데 사용되는 모든 특수 트릭이 트랩 된 명령을 작성할 때 작동한다는 것입니다. 유일한 차이점은 배열 구문을 사용해야한다는 것입니다.

예 :

"$ @"을 원하면 "$ {CMD_ARGV [@]}"을 사용하십시오.

"$ #"을 원하는 경우 "$ {# CMD_ARGV [@]}"을 사용하십시오.

기타.


3

일단 재미있는 프로젝트 를 했는데도 여전히 사용합니다. cpcoz 명령을 통해 파일을 복사하는 동안 애니메이션이 cp표시되지 않고 아무것도 표시되지 않으며 다소 실망 스럽습니다. 이 별칭을 만들었습니다

alias cp="~/SCR/spiner cp"

그리고 이것은 스피너 스크립트입니다

#!/bin/bash

#Set timer
T=$(date +%s)

#Add some color
. ~/SCR/color

#Animation sprites
sprite=( "(* )  ( *)" " (* )( *) " " ( *)(* ) " "( *)  (* )" "(* )  ( *)" )

#Print empty line and hide cursor
printf "\n${COF}"

#Exit function
function bye { printf "${CON}"; [ -e /proc/$pid ] && kill -9 $pid; exit; }; trap bye INT

#Run our command and get its pid
"$@" & pid=$!

#Waiting animation
i=0; while [ -e /proc/$pid ]; do sleep 0.1

    printf "\r${GRN}Please wait... ${YLW}${sprite[$i]}${DEF}"
    ((i++)); [[ $i = ${#sprite[@]} ]] && i=0

done

#Print time and exit
T=$(($(date +%s)-$T))
printf "\n\nTime taken: $(date -u -d @${T} +'%T')\n"

bye

이렇게 생겼어요

여기에 이미지 설명을 입력하십시오

순환 애니메이션)

여기에 이미지 설명을 입력하십시오


2

매개 변수를 사용하려면 기능을 사용해야합니다!

그러나 별칭을 실행하는 대신 별칭을 만들 때 $ @가 해석되고 $를 이스케이프해도 작동하지 않습니다. 이 문제를 어떻게 해결합니까?

이 문제를 해결하려면 별명 대신 쉘 기능을 사용해야합니다. 다음과 같이 foo를 정의 할 수 있습니다.

function foo() { /path/to/command "$@" ;}

또는

foo() { /path/to/command "$@" ;}

마지막으로 다음 구문을 사용하여 foo ()를 호출하십시오.

foo arg1 arg2 argN

확실히 당신은 () 당신의 foo는 추가로 확인 ~/.bash_profile하거나 ~/.zshrc파일.

귀하의 경우이 작동합니다

function trash() { mv $@ ~/.Trash; }

나는 당신의 생각을 이해하지 못합니다. 나는 논쟁이 해석 될 때 중요하지 않다고 생각한다. 별명은 끝에 원하는만큼 많은 매개 변수를 승인합니다.
Timo

그러나 함수로 그렇게하는 것이 좋습니다. 별칭은 그런 의미가 아닙니다.
Ahmad Awais

1

함수는 실제로 맨 페이지의이 인용문에 의해 이미 충분히 기여하고 확인 된대로 거의 항상 답입니다. "거의 모든 목적에서 별명은 쉘 함수로 대체됩니다."

완전성을 위해 이것이 유용 할 수 있기 때문에 (약간의 가벼운 구문), 매개 변수가 별명을 따를 때에도 여전히 사용될 수 있다는 것을 알 수 있습니다 (그러나 이것은 OP의 요구 사항을 다루지는 않지만). 이것은 예제로 가장 쉽게 설명 할 수 있습니다.

alias ssh_disc='ssh -O stop'

다음과 같이 smth를 입력하면 다음과 같이 ssh_disc myhost확장됩니다.ssh -O stop myhost

이것은 복잡한 인수를 취하는 명령에 유용 할 수 있습니다 (메모리는 더 이상 사용되지 않습니다 ...)


1

함수와 별칭 모두 다른 사람이 여기에 표시된 것처럼 매개 변수를 사용할 수 있습니다. 또한 몇 가지 다른 측면을 지적하고 싶습니다.

1. 기능은 자체 범위, 별칭 공유 범위에서 실행됩니다.

무언가를 숨기거나 노출해야하는 경우이 차이를 아는 것이 유용 할 수 있습니다. 또한 캡슐화에 함수가 더 나은 선택임을 제안합니다.

function tfunc(){
    GlobalFromFunc="Global From Func" # Function set global variable by default
    local FromFunc="onetwothree from func" # Set a local variable

}

alias talias='local LocalFromAlias="Local from Alias";  GlobalFromAlias="Global From Alias" # Cant hide a variable with local here '
# Test variables set by tfunc
tfunc # call tfunc
echo $GlobalFromFunc # This is visible
echo $LocalFromFunc # This is not visible
# Test variables set by talias
# call talias
talias
echo $GlobalFromAlias # This is invisible
echo $LocalFromAlias # This variable is unset and unusable 

산출:

bash-3.2$     # Test variables set by tfunc
bash-3.2$     tfunc # call tfunc
bash-3.2$     echo $GlobalFromFunc # This is visible
Global From Func
bash-3.2$     echo $LocalFromFunc # This is not visible

bash-3.2$     # Test variables set by talias
bash-3.2$     # call talias
bash-3.2$     talias
bash: local: can only be used in a function
bash-3.2$     echo $GlobalFromAlias # This is invisible
Global From Alias
bash-3.2$ echo $LocalFromAlias # This variable is unset and unusable

2. 래퍼 스크립트가 더 나은 선택입니다

사용자 이름 또는 다중 사용자 환경 전환 을 통해 로그인ssh 하거나 로그인 할 때 별칭 또는 기능을 찾을 수없는 경우가 여러 번 발생했습니다 . 도트 파일 또는 별칭이 흥미로운 소싱과 팁과 트릭이 있습니다 alias sd='sudo '이 이후의 별명 할 수 있습니다 alias install='sd apt-get install'(통지에 여분의 공간 예상대로 일을 sd='sudo '). 그러나 랩퍼 스크립트는 이와 같은 경우 함수 또는 별명보다 더 잘 작동합니다. 랩퍼 스크립트의 주요 장점은 의도 된 경로 (예 : / usr / loca / bin /)에서 가시적 / 실행 가능하다는 것입니다. 예를 들어 ~ / .bash_profile 또는 ~ / .bashrc에 함수를 넣었 bash지만 나중에 다른 셸 (예 :zsh) 함수가 더 이상 보이지 않습니다. 따라서 의심스러운 경우 래퍼 스크립트는 항상 가장 신뢰할 수 있고 이식 가능한 솔루션입니다.


1
기능 버전이 작동하지 않는 이유는 무엇입니까?
tripleee

@tripleee. 게시물을 더 읽기 쉽게 편집했습니다. "1. alias works, function ..."제목 아래에서 함수 버전이 작동하지 않는 이유를 설명했습니다. 그리고 아마도 질문에 직접 대답하기 위해 함수는 별칭이없는 새로운 범위를 소개합니다.
biocyberman

당신은 그것이 작동하지 않는다고 말하지만 나는 당신을 믿지 않습니다. source함수에서 잘 작동합니다.
tripleee

1
f () { source /tmp/nst; }내가 기대하는 것을 정확하게 수행합니다. 어쩌면 당신 PATH이 잘못되어서 잘못 activate되거나 무언가를 실행했을 수도 있습니다 . 그러나 source함수에서 실행 하면 정상적으로 작동합니다.
tripleee

1
BTW, re : function정의에 키워드를 사용하는 방법 은 wiki.bash-hackers.org/scripting/obsolete를 참조하십시오 - function funcname {고대 ksh 구문 bash는 POSIX 이전 버전과의 호환성을 위해 bash가 지원하는 반면 funcname() {공식 POSIX 표준 구문입니다. function funcname() {는 고대 ksh 호환 되지 않거나 POSIX sh와 호환 되지 않으므로 피하는 것이 가장 좋습니다.
Charles Duffy

1

예를 들면 다음과 같습니다.

alias gcommit='function _f() { git add -A; git commit -m "$1"; } ; _f'

매우 중요:

  1. 뒤에 공백이 {및 이전은 }.
  2. ;순서대로 각 명령. 마지막 명령 후에 이것을 잊어 버리면 >대신 프롬프트 가 표시 됩니다!
  3. 인수는 다음과 같이 따옴표로 묶습니다. "$1"

2
함수에 대한 별칭을 만들 필요가 없으며 함수를 직접 사용하십시오.
user3439894

1

다른 사람들이 이미 지적했듯이 기능 사용은 모범 사례로 간주해야합니다.

그러나 여기에 다른 접근 방식이 있습니다 xargs.

alias junk="xargs -I "{}" -- mv "{}" "~/.Trash" <<< "

이는 스트림 리디렉션과 관련된 부작용이 있습니다.


0

별도의 작업을 수행 할 필요가 없습니다. 별칭이 자동으로 수행합니다.

예를 들어, git pull origin master를 매개 변수화하려면 다음과 같이 별칭을 만들 수 있습니다.

alias gpull = 'git pull origin '

실제로 호출 할 때 다음과 같이 'master'(분기 이름)를 매개 변수로 전달할 수 있습니다.

gpull master
//or any other branch
gpull mybranch

논쟁을 자유롭게 할 수는 없지만 끝에 만 놓을 수 있기 때문에 질문에 대답하지 않습니다.
dirdi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.