#TIL #git origin 리모트 저장소 변경

$ cd existing_repo
$ git remote rename origin old-origin
$ git remote add origin new_repo_url
$ git push -u origin --all
$ git push -u origin --tags
$ git remote remove old-origin

저장소를 만드니 gitlab이 안내해줬다.

$ git remote remove origin

이름 변경 없이 지운 후에 진행해도 된다.

u 옵션을 붙여서 upstream 설정도 같이해준다. 로컬 브랜치가 tracking 하는 리모트 브랜치다. 이 정보가 없으면 push를 할 때, 매번 로컬 브랜치와 리모트 브랜치를 적어줘야 한다.

#TIL #batch 5초 sleep

C:\> ping 127.0.0.1 -n 6 > nul

ping 사이에 1초 delay라서 5가 아닌 6을 넘긴다.

C:\> timeout /t 5

timeout 명령어를 사용해도 된다.

참고 - Sleeping in a batch file - stackoverflow.com

#TIL #elixir require as

require MyMacros
alias MyMacros, as: My

alias를 따로 안 써도 된다.

require MyMacros, as: My

requireas 옵션을 사용해 한 줄로 끝.

#TIL #bash 스크립트에서 실패 커맨드를 성공으로 처리하고 싶다면

#!/usr/bin/env bash

set -e

docker kill some_container 2>/dev/null || true

에러 스노우볼링을 막으려고 제일 먼저 set -e 명령어를 실행한다. 깐깐하게 모든 리턴 값을 검사해서 0이 아니면 종료하는 건 좋다. 기조는 이렇게 가지고 가더라도 봐줄 건 봐주자. 대충 넘어가고 싶은 명령어에 쓸 수 있는 트릭이다.

앞에 명령이 실패하면 true 커맨드가 실행된다. 항상 0을 리턴하는 true를 사용해서 실패하지 않는 명령어로 만들었다.

참고 - stop and delete docker container if its running - stackoverflow.com

#TIL #csharp 객체 이니셜라이저 (object initializers)

Cat cat = new Cat()
cat.Age = 10;
cat.Name = "Fluffy";

unity가 아무리 옛날 .NET Framework 3.5를 지원한다고 해도 그렇지. 이건 이상하다. 이렇게 불편할 리가 없는데.

Cat cat = new Cat { Age = 10, Name = "Fluffy" };

그래. 최소한 이거지. 객체 이니셜라이저를 사용할 수 있다. unity에서도 사용할 수 있다. 객체 이니셜라이저는 C# 3.0에 추가됐고 .NET Framework 3.5에 포함됐다.

참고 - 객체 및 컬렉션 이니셜라이저(C# 프로그래밍 가이드) - docs.microsoft.com

#TIL #linux CR LF를 LF로 바꿔야 할 때는 dos2unix

standard_init_linux.go:175: exec user process caused "no such file or directory"

docker for windows에서 본 에러 메시지. 뭐가 문제인 거지?

root@bbfb0023c2df:/usr/local/bin# ./entrypoint.sh
bash: ./entrypoint.sh: /bin/bash^M: bad interpreter: No such file or directory

조물딱 거리다 보니 다른 에러 메시지가 나왔다. 아~ 라인엔딩 때문이다. windows 환경에서 작성한 entrypoint.sh 파일을 docker 컨테이너에서 실행한다. LF만 쓰는 리눅스에서 CR LF를 사용한 파일을 실행하다 문제가 생긴 거.

RUN apt-get update && apt-get install -y dos2unix
COPY entrypoint.sh /entrypoint.sh
RUN dos2unix /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

복사 후 dos2unix 프로그램으로 라인엔딩을 바꿔주면 된다.

참고 - Docker for Windows: Dealing With Windows Line Endings - willi.am/blog

#TIL #bash #batch 스크립트 파일이 있는 부모 디렉터리로 cd

cd "$(dirname "$0")/.."

bash에서는 $0 스페셜 파라미터를 사용한다.

$ cat script_path_test
echo "$(dirname "$0")/.."

이런 스크립트 파일이 있을 때, 어디에서 실행하느냐에 따라 출력 결과가 달라진다.

$ pwd
/c/Users/ohyecloudy/test

$ ./script_path_test
./..

스크립트 파일이 있는 디렉터리에서 실행한 결과.

$ pwd
/c/Users/ohyecloudy

$ test/script_path_test
test/..

부모 디렉터리에서 실행한 결과.

다른 디렉터리에서 실행할 수 있기 때문에 그냥 cd .. 명령을 쓰면 안 된다. 대신 $0 스페셜 파라미터를 사용하면 된다. 위 예에선 각각 ./script_path_test, test/script_path_test로 확장한다. dirname을 사용해 디렉터리를 추출하고 부모 디렉터리로 cd를 하면 스크립트 파일이 있는 부모 디렉터리로 작업 디렉터리를 바꿀 수 있다.

pushd %cd%
cd %~dp0..
popd

batch 스크립트에서는 %~dp0 스페셜 파라미터를 사용하면 된다. 스크립트 환경 분리가 안 돼서 현재 디렉터리를 push, pop 해줘야 스크립트 실행 후 작업 디렉터리가 바뀌지 않는다.

참고

#TIL #batch #bash redirection 연산자를 앞으로 당겨도 되잖아

 >result.txt echo first line
>>result.txt echo second line
>>result.txt echo third line

이렇게 써도 되다니. 칼각에 마음이 평온해진다. batch, bash 모두 된다. 자연스럽게 공백 방지도 된다.

참고 - The redirection can come anywhere on the line, and you can use that to get rid of the spaces - The Old New Thing

#TIL #vim b 키와 방향은 같지만 도착지는 다른 ge 키

| ge | Backward to the end of word |
| gE | Backward to the end of WORD |

몰라도 불편한 건 없다. 낮은 사용 빈도 때문인지 키도 두 개 눌러야 한다. 몰라서 나쁠 건 없다. 특히 매크로 정의할 때, 몰라도 어찌 할 수 있지만 번거로운 건 사실이다.

evil backward-word en|d

ge

evil backward-wor|d end

ge

evil backward|-word end

이전 위치에서 gE

evi|l backward-word end

참고

#TIL #vim 이전 visual mode로 선택한 영역을 다시 선택하려면

V 키를 눌러 visual mode 진입 후 영역을 선택한다. < 키를 눌러 왼쪽으로 옮긴다. 에이 2< 키 누를걸. 한 번 더 밀어야 하잖아. 이때 gv 키를 눌러 이전과 똑같은 영역을 선택한다. 그리고 다시 < 키를 누르면 된다.

참고

#TIL #vim 변경이 일어난 곳을 기억한다

vim은 변경이 일어난 곳을 기억한다. 끝이 안 보이는 문서에서 마지막 수정한 위치로 가려고 u 키로 undo를 해서 가던 무식한 날들은 이제 안녕.

| :changes | Print the change list                              |
| g;       | Go to [count] older position in change list        |
| g,       | Go to [count] newer cursor position in change list |

참고

#TIL #bash 큰따옴표 안에 있는 물결표(Tilde)는 확장 안 된다

$ MD="~/My Documents"
$ echo "${MD}"
~/My Documents
$ cd "${MD}"
bash: cd: ~/My Documents: No such file or directory

물결표(~)는 HOME 환경 변수값으로 확장한다. 그런데, 확장이 안 된다. 이상하다.

$ MD=~/My\ Documents
$ echo "${MD}"
/c/Users/ohyecloudy/My Documents
$ cd "${MD}"
$ pwd
/c/Users/ohyecloudy/My Documents

큰따옴표(double quotes) 안에 있으면 확장 안 되는 것 아닐까? 큰따옴표를 쓰니 물결표 그대로 쓰이는 것 같다.

Enclosing characters in double quotes (‘”’) preserves the literal value of all characters within the quotes, with the exception of ‘$’, ‘`’, ‘\’, and, when history expansion is enabled, ‘!’. - 3.1.2.3 Double Quotes

아~ 확장되는 문자 중에 물결표는 없어요.

$ MD="$HOME/My Documents"
$ cd "${MD}"
$ pwd
/c/Users/ohyecloudy/My Documents

큰따옴표 안 쓰면 된다. 아니면 물결표 대신 $HOME 환경 변수값으로 확장해주면 된다.

참고

#TIL #bash 셸 파라미터 확장 - 공백을 포함한 path

$ cd My\ Documents
$ pwd
/c/Users/ohyecloudy/My Documents

parameter에 공백이 있는 경로를 할당하고 cd 명령어 인자로 넘기려면?

$ MD=My\ Documents
$ cd $MD
bash: cd: too many arguments
$ cd "$MD"
$ pwd
/c/Users/ohyecloudy/My Documents

path가 공백을 포함하려면 큰따옴표(double quotes)로 감싸야 한다.

$ MD="My Documents"
$ cd $MD
bash: cd: too many arguments
$ cd "$MD"

이건 또 왜? 이미 큰따옴표로 감쌌잖아. 그냥 써도 될 것 같은데. 셸 파라미터 확장(shell parameter expansions) 후에 뭔가 일어나는 것 같다.

After the preceding expansions, all unquoted occurrences of the characters ‘\’, ‘’’, and ‘”’ that did not result from one of the above expansions are removed. - 3.5.9 Quote Removal

맞네. \, ‘, ” 문자는 제거된다. 그래서 큰따옴표로 감싸야 한다.

참고

#TIL #vim goto file, goto definition

g d 키는 로컬 정의(local definition)로 이동하고 g D 키는 글로벌 정의로 이동한다. 소스 코드에서 많이 사용한다. g d 키를 눌러서 정의를 보고 Ctrl o 키를 눌러서 원래 자리로 온다.

g f 키는 파일 이름처럼 생긴 문자열이 커서에 있으면 파일을 연다. g F 키는 더 친절하다. eval.c:10 식으로 라인 번호가 있으면 라인까지 데려다준다.

참고

#TIL #vim rain 위에서 * 키는 rainbow를 찾지 못한다

/ddiary/assets/2018-01-31-til-vim-search-unbounded-word-forward-00.gif

* 키는 /\<rain\> 검색 패턴으로 찾는다. \<, \> 패턴으로 감쌌기 때문에 단어가 일치해야 한다. 반면 g * 키는 /rain 검색 패턴으로 찾는다. 단어 일치를 검사하지 않는다.

참고 - Search patterns - vim.wikia.com

#TIL #macOS 스크린샷 찍는 단축키

Command(⌘)-Shift-3

전체 화면 찍기.

Command(⌘)-Shift-4

영역을 선택할 수 있다.

Command(⌘)-Shift-4, 스페이스 바

이걸 이번에 알았다. 메뉴막대 혹은 윈도우를 깔끔하게 찍을 수 있다.

참고 - Mac에서 스크린샷을 찍는 방법 - support.apple.com

#TIL #elixir iex에서 모듈을 재컴파일하는 법

iex> c("lib/worker.ex")

모듈을 정의한 파일을 컴파일했는데

iex> r(Test.Worker)

그냥 모듈 이름만 넣어도 된다. iex에서 로드할 때, 파일 정보도 기록하는 모냥.

M-x alchemist-iex-reload-module

emacs를 사용한다면 alchemist를 놓칠 수 없다. 편집하던 버퍼에서 함수를 호출하면 된다.

링크 - IEx.Helpers.r/1

#TIL #elixir 생각해보니 MapSet.subset?

MapSet.size(MapSet.difference(a, b)) == 0

잠깐. 이상하잖아.

MapSet.subset?(a, b)

뭘 저렇게 복잡하게 하려고 했나? MapSet.subset?/2 함수랑 같다.

#TIL #elixir ! 문자로 끝나는 함수 이름 컨벤션

Enum.fetch/2, Enum.fetch!/2 함수의 차이점은? 에러 발생 여부다

iex> Enum.fetch([2, 4, 6], 2)
{:ok, 6}

iex> Enum.fetch([2, 4, 6], 4)
:error

:error 리턴. 튜플 리턴이 기본값.

iex> Enum.fetch!([2, 4, 6], 2)
6

iex> Enum.fetch!([2, 4, 6], 4)
** (Enum.OutOfBoundsError) out of bounds error

에러 발생. 원소값 리턴이 기본값.

느낌표 따위 함수 이름으로 얼마든지 쓸 수 있다. 에러를 일으키는 함수 이름 끝에는 ! 문자를 붙인다.

#TIL #vim #visual_studio #emacs jump forward, backword 키바인딩 통일

vim은 커서 위치를 jump list로 관리한다. `, /, n 등 커맨드로 이동할 때, 위치를 기록해 놓는다. 커서 위치를 바꾼다고 모두 저장하진 않는다. hjkl 키처럼 깨작깨작 움직이는 커맨드는 제외한다. jump list에 기록된 위치를 CTRL-I 키와 CTRL-O 키로 앞뒤로 점프할 수 있다.

:ju[mps]

jump list를 볼 수 있다.

visual studio

View.NavigateBackward, View.NavigateForward 동작을 각각 CTRL-O, CTRL-I 키로 바인딩하면 똑같이 사용할 수 있다.

emacs evil-mode

| C-i    | evil-jump-forward  |
| C-o    | evil-jump-backward |
| :jumps | evil-show-jumps    |

emacs에서는 evil-mode 패키지를 설치하면 사용할 수 있다.