<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
  <channel>
    <title>Bang Seongbeom</title>
    <link>https://www.bangseongbeom.com/</link>
    <description>Developer Bang Seongbeom&#39;s technical documentation.</description>
    <language>en</language>
    
    <managingEditor>bangseongbeom@gmail.com (방성범 (Bang Seongbeom))</managingEditor>
    <webMaster>bangseongbeom@gmail.com (방성범 (Bang Seongbeom))</webMaster>
    
    <lastBuildDate>Sat, 09 May 2026 03:19:30 GMT</lastBuildDate>
    
    
    <docs>https://www.rssboard.org/rss-specification</docs>
    <atom:link href="https://www.bangseongbeom.com/feed.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>404 Not Found</title>
      <link>https://www.bangseongbeom.com/404</link>
      <description>&lt;h1 id=&quot;404-not-found&quot;&gt;404 Not Found&lt;/h1&gt;
</description>
      
      <pubDate>Sat, 09 Aug 2025 04:07:04 GMT</pubDate>
      <guid>https://www.bangseongbeom.com/404</guid>
      
    </item>
    <item>
      <title>Bang Seongbeom</title>
      <link>https://www.bangseongbeom.com/</link>
      <description>&lt;h1 id=&quot;bang-seongbeom&quot;&gt;Bang Seongbeom&lt;/h1&gt;
&lt;p&gt;Developer Bang Seongbeom&#39;s technical documentation.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/android&quot;&gt;Android&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/git&quot;&gt;Git&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/iot&quot;&gt;IoT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/java&quot;&gt;Java&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/linux&quot;&gt;Linux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/machine-learning&quot;&gt;Machine learning&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/misc&quot;&gt;Misc.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/python&quot;&gt;Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/web&quot;&gt;Web&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
      
      <pubDate>Sun, 01 Jun 2025 02:02:59 GMT</pubDate>
      <guid>https://www.bangseongbeom.com/</guid>
      
    </item>
    <item>
      <title>셀레늄 IDE 가이드</title>
      <link>https://www.bangseongbeom.com/selenium-ide-guide/</link>
      <description>&lt;h1 id=&quot;셀레늄-ide-가이드&quot;&gt;셀레늄 IDE 가이드&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://www.selenium.dev/selenium-ide/&quot;&gt;셀레늄 IDE&lt;/a&gt;(Selenium IDE)는 사용자가 웹 브라우저에서 수행한 동작을 기록하고, 이를 다시 재현합니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;duckduckgo.gif&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;설치&quot;&gt;설치&lt;/h2&gt;
&lt;p&gt;크롬 확장 기능 또는 파이어폭스 플러그인으로 셀레늄 IDE를 사용할 수 있습니다. &lt;a href=&quot;https://www.selenium.dev/selenium-ide/&quot;&gt;셀레늄 IDE 공식 홈페이지&lt;/a&gt;에서 플러그인을 설치하세요.&lt;/p&gt;
&lt;div class=&quot;markdown-alert markdown-alert-note&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Note&lt;/p&gt;
&lt;p&gt;이 글에서 소개하는 셀레늄 IDE는 버전 3입니다. 버전 4는 현재 개발 중이며, 브라우저 없이 독립 실행 가능하도록 &lt;a href=&quot;https://www.electronjs.org/&quot;&gt;일렉트론&lt;/a&gt;(Electron) 기반으로 구현되고 있습니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-electron&quot; id=&quot;fnref-electron&quot; data-footnote-ref=&quot;&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;기록&quot;&gt;기록&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;record-a-new-test-in-a-new-project.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;셀레늄 IDE를 실행한 뒤 곧바로 &#39;Record a new test in a new project&#39;를 클릭해 기록을 시작할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;start-recording.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;또는 &#39;Start recording&#39;을 눌러 기록을 시작할 수도 있습니다.&lt;/p&gt;
&lt;p&gt;기록을 시작하기 전에 먼저 &lt;strong&gt;프로젝트 이름&lt;/strong&gt;과 &lt;strong&gt;베이스 URL&lt;/strong&gt;을 설정해야 합니다.&lt;/p&gt;
&lt;h3 id=&quot;용어-설명-프로젝트&quot;&gt;용어 설명: 프로젝트&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;project-name-2.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;셀레늄 IDE는 프로젝트 단위로 파일을 저장하거나 불러옵니다. 이때 사용할 프로젝트 이름을 미리 설정해야 합니다.&lt;/p&gt;
&lt;p&gt;프로젝트 파일은 &lt;code&gt;.side&lt;/code&gt; 확장자로 저장됩니다. &lt;code&gt;.side&lt;/code&gt;는 내부적으로 &lt;a href=&quot;https://www.json.org/&quot;&gt;JSON&lt;/a&gt; 형태를 가집니다.&lt;/p&gt;
&lt;h3 id=&quot;용어-설명-베이스-url&quot;&gt;용어 설명: 베이스 URL&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;base-url-2.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;베이스 URL(base URL)은 기록을 처음 실행할 때 시작할 웹 사이트의 URL입니다.&lt;/p&gt;
&lt;p&gt;하나의 프로젝트 당 하나의 베이스 URL을 가질 수 있습니다. 각 테스트 별로 베이스 URL을 지정할 수는 없습니다.&lt;/p&gt;
&lt;h3 id=&quot;기록을-위한-새-창&quot;&gt;기록을 위한 새 창&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;selenium-ide-is-recording.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;기록이 시작되면 새로운 웹 브라우저 창이 열립니다. 기록 중이라는 메시지가 브라우저 오른쪽 아래에 나옵니다. 이제 이 브라우저에서 기록하고자 하는 동작을 수행하면 됩니다.&lt;/p&gt;
&lt;p&gt;사용자가 행하는 동작은 &lt;strong&gt;명령어&lt;/strong&gt;로 기록됩니다.&lt;/p&gt;
&lt;h3 id=&quot;용어-설명-명령어&quot;&gt;용어 설명: 명령어&lt;/h3&gt;
&lt;p&gt;명령어(command)는 클릭하기, 타이핑하기, 브라우저 창 크기 조절하기와 같이 브라우저에서 행하는 동작을 의미합니다. 기록되는 동안 웹 브라우저에 대한 조작이 명령어로 만들어집니다.&lt;/p&gt;
&lt;h2 id=&quot;실행&quot;&gt;실행&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;run-current-test.gif&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&#39;Run current test&#39; 버튼을 눌러 기록한 명령어들을 실행합니다. 새로운 웹 브라우저가 열리며 명령어에 따라 순차적으로 동작합니다.&lt;/p&gt;
&lt;h2 id=&quot;저장&quot;&gt;저장&lt;/h2&gt;
&lt;p&gt;&#39;Save project&#39; 버튼을 눌러 프로젝트를 저장합니다.&lt;/p&gt;
&lt;div class=&quot;markdown-alert markdown-alert-note&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Note&lt;/p&gt;
&lt;p&gt;웹 브라우저 환경에서는 그 특성 상 특정 파일의 경로에 직접적으로 파일을 쓰거나 읽을 수 없습니다. 반드시 &#39;다른 이름으로 저장&#39;이나 &#39;열기&#39;를 통해 사용자가 직접 읽거나 쓸 파일을 선택해야 합니다. 이러한 이유로 인해 셀레늄 IDE는 프로젝트를 저장할 때마다 매번 저장할 위치를 지정해야 하는 번거로움이 있습니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-why-location-not-remembered&quot; id=&quot;fnref-why-location-not-remembered&quot; data-footnote-ref=&quot;&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id=&quot;저장되지-않음-표시&quot;&gt;저장되지 않음 표시&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;not-saved.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;프로젝트, 테스트, 테스트 스위트 이름 뒤에 &#39;*&#39;이 붙어있을 때가 있습니다. 이는 변경된 내용이 아직 저장되지 않았음을 의미합니다.&lt;/p&gt;
&lt;h2 id=&quot;테스트테스트-스위트-목록&quot;&gt;테스트/테스트 스위트 목록&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;test-area.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;아래 화살표 버튼을 눌러 테스트와 테스트 스위트 목록을 전환할 수 있습니다. (이외에도 &#39;Executing&#39;이라는 목록이 있습니다. 이 목록은 현재 실행 중인 테스트를 보여줍니다.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;테스트에 관한 설정은 테스트 목록에서, 테스트 스위트에 관한 설정은 테스트 스위트 목록에서만 가능합니다.&lt;/strong&gt; 테스트 스위트 목록인 상태에서는 테스트를 생성할 수 없습니다. 그 반대도 마찬가지입니다.&lt;/p&gt;
&lt;h3 id=&quot;용어-설명-테스트&quot;&gt;용어 설명: 테스트&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;tests.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;테스트(test)는 여러 &lt;strong&gt;명령어&lt;/strong&gt;들을 순서대로 나열해놓은 것입니다. 하나의 &lt;strong&gt;프로젝트&lt;/strong&gt;에 여러 테스트가 존재할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;markdown-alert markdown-alert-note&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Note&lt;/p&gt;
&lt;p&gt;이것이 테스트라고 불리는 이유는, 이 용어가 &lt;a href=&quot;https://junit.org/junit5/docs/current/user-guide/#writing-tests-classes-and-methods&quot;&gt;J유닛의 테스트&lt;/a&gt;와 관련이 있기 때문으로 보입니다. 셀레늄 IDE는 작성한 테스트를 J유닛의 테스트로 내보낼 수 있는 기능을 제공하는데요(하단 참조), 이때 셀레늄 IDE의 테스트 하나는 J유닛의 테스트 하나로 변환됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id=&quot;용어-설명-테스트-스위트&quot;&gt;용어 설명: 테스트 스위트&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;test-suites.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;테스트 스위트(test suite)는 여러 테스트의 집합입니다. 테스트 스위트를 이용해 테스트를 목적에 따라 분류할 수 있습니다.&lt;/p&gt;
&lt;p&gt;테스트가 새로 만들어지면 기본적으로 &#39;Default Suite&#39;에 속합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;주의:&lt;/strong&gt; 하나의 테스트는 여러 테스트 스위트에 속할 수도 있고, 그 어떤 테스트 스위트에도 속하지 않을 수도 있습니다.&lt;/p&gt;
&lt;div class=&quot;markdown-alert markdown-alert-note&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Note&lt;/p&gt;
&lt;p&gt;앞서 언급한 테스트의 사례처럼, 이것을 테스트 스위트라 부르는 이유 역시 &lt;a href=&quot;https://junit.org/junit5/docs/current/user-guide/#running-tests-junit-platform-runner-test-suite&quot;&gt;J유닛의 테스트 스위트&lt;/a&gt;에서 따왔습니다. 셀레늄 IDE의 테스트 스위트 하나는 J유닛의 테스트 스위트 하나로 변환됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id=&quot;테스트-테스트-스위트-추가&quot;&gt;테스트, 테스트 스위트 추가&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;add-new-test.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;테스트 목록인 상태에서 &#39;+&#39; 버튼을 눌러 테스트를 추가할 수 있습니다. 테스트 스위트 역시 마찬가지입니다.&lt;/p&gt;
&lt;p&gt;주의할 점은 테스트 추가는 테스트 목록에서만, 테스트 스위트 추가는 테스트 스위트 목록에서만 가능하다는 것입니다. &lt;strong&gt;테스트 목록인 상태에서 테스트 스위트를 추가할 수는 없습니다.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;검색&quot;&gt;검색&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;search-tests.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;검색어를 입력해 테스트를 찾을 수 있습니다.&lt;/p&gt;
&lt;h3 id=&quot;이름-바꾸기-복제-삭제&quot;&gt;이름 바꾸기, 복제, 삭제&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;test-options-1.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;test-options-2.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&#39;⋮&#39; 버튼을 눌러 이름을 바꾸거나 테스트 또는 테스트 스위트를 복제, 삭제할 수 있습니다.&lt;/p&gt;
&lt;h3 id=&quot;테스트-스위트에-테스트-포함시키기&quot;&gt;테스트 스위트에 테스트 포함시키기&lt;/h3&gt;
&lt;p&gt;테스트 스위트 목록인 상태에서 &#39;⋮&#39; 버튼을 클릭한 뒤, &#39;Add tests&#39;를 눌러 테스트 스위트에 테스트를 포함시킬 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;markdown-alert markdown-alert-note&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Note&lt;/p&gt;
&lt;p&gt;이 작업이 테스트를 &lt;strong&gt;생성&lt;/strong&gt;하는 것은 아닙니다. 테스트를 생성하기 위해서는 반드시 &lt;strong&gt;테스트 목록인 상태&lt;/strong&gt;에서 &#39;+&#39; 버튼을 클릭해 테스트를 생성해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id=&quot;내보내기&quot;&gt;내보내기&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;export-1.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;export-2.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;export-3.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;내보내기는 특정 테스트 혹은 테스트 스위트를 프로그래밍 언어로 변환할 수 있는 기능입니다. 자바의 J유닛(JUnit), 파이썬의 파이테스트(pytest)와 같은 테스트 프레임워크 기반의 코드가 생성됩니다.&lt;/p&gt;
&lt;p&gt;현재 다음과 같은 언어 및 테스트 프레임워크를 지원합니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-supported-exports&quot; id=&quot;fnref-supported-exports&quot; data-footnote-ref=&quot;&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;C# N유닛(NUnit)&lt;/li&gt;
&lt;li&gt;C# x유닛(xUnit)&lt;/li&gt;
&lt;li&gt;자바 J유닛(JUnit)&lt;/li&gt;
&lt;li&gt;자바스크립트 모카(Mocha)&lt;/li&gt;
&lt;li&gt;파이썬 파이테스트(pytest)&lt;/li&gt;
&lt;li&gt;루비 R스펙(RSpec)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;새로운 언어나 테스트 프레임워크가 필요하다면 &lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/introduction/code-export#how-to-contribute&quot;&gt;셀레늄 IDE에 기여&lt;/a&gt;해보세요.&lt;/p&gt;
&lt;h2 id=&quot;실행-및-관련-설정&quot;&gt;실행 및 관련 설정&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;run-area.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;div class=&quot;markdown-alert markdown-alert-note&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Note&lt;/p&gt;
&lt;p&gt;여기서는 GUI로 실행하는 방법에 대해 다룹니다. CLI로 실행하는 방법은 이 글의 후반부에서 설명합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id=&quot;전체-실행&quot;&gt;전체 실행&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;run-all-tests.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;좌측에 테스트 목록을 보이게 한 상태에서 &#39;Run all tests&#39; 버튼을 눌러 모든 테스트를 실행합니다.&lt;/p&gt;
&lt;p&gt;좌측에 테스트 스위트 목록을 보이게 한 상태에서는 버튼(&#39;Run all tests in suite&#39;)의 동작이 테스트 스위트 내의 모든 테스트를 실행하는 것으로 바뀝니다.&lt;/p&gt;
&lt;h3 id=&quot;현재-테스트-실행&quot;&gt;현재 테스트 실행&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;run-current-test.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&#39;Run current test&#39; 버튼을 눌러 현재 활성화한 테스트를 실행할 수 있습니다.&lt;/p&gt;
&lt;h3 id=&quot;한-줄씩-실행&quot;&gt;한 줄씩 실행&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;step-over-current-command.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&#39;Step over current command&#39; 버튼을 눌러 테스트를 한 줄씩 실행할 수 있습니다.&lt;/p&gt;
&lt;h3 id=&quot;테스트-실행-속도-조절&quot;&gt;테스트 실행 속도 조절&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;test-execution-speed.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&#39;Test execution speed&#39; 버튼을 눌러 테스트의 실행 속도를 조절할 수 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;명령어&quot;&gt;명령어&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;command-area.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;셀레늄 IDE는 조건문이나 반복문 같이 프로그래밍 언어에서 지원할 법한 명령어도 제공합니다. 이러한 명령어는 웹 브라우저의 사용을 기록하는 방식으로 만들 수는 없고, 대신 직접 명령어를 추가해야 합니다.&lt;/p&gt;
&lt;div class=&quot;markdown-alert markdown-alert-note&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/api/commands&quot;&gt;Commands - Selenium IDE&lt;/a&gt;에서 셀레늄 IDE가 제공하는 모든 명령어를 확인하세요.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id=&quot;중단점&quot;&gt;중단점&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;breakpoints.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;셀레늄 IDE는 테스트 실행 도중 특정 명령어에서 일시정지할 수 있는 기능을 제공하는데, 이를 중단점(breakpoint)이라 합니다.&lt;/p&gt;
&lt;p&gt;명령어의 &lt;strong&gt;왼쪽 번호&lt;/strong&gt;를 클릭해 중단점을 지정합니다.&lt;/p&gt;
&lt;p&gt;테스트 실행 중 중단점을 만나면 테스트가 일시정지됩니다. &#39;Run current test&#39;를 눌러 테스트를 계속 진행할 수 있습니다.&lt;/p&gt;
&lt;h3 id=&quot;중단점-비활성화&quot;&gt;중단점 비활성화&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;disable-breakpoints.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&#39;Disable breakpoints&#39;는 모든 중단점을 비활성화합니다. 중단점을 만나도 테스트가 일시정지되지 않게 됩니다.&lt;/p&gt;
&lt;h3 id=&quot;예외-발생-시-정지&quot;&gt;예외 발생 시 정지&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;pause-on-exceptions.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;웹 사이트의 변경으로 인해 클릭해야 할 버튼이 없어진다거나 하는 문제가 생길 수 있습니다. 이를 가리켜 예외라 합니다.&lt;/p&gt;
&lt;p&gt;셀레늄 IDE는 일반적으로 예외가 발생하면 테스트를 종료합니다. &#39;Pause on exceptions&#39; 버튼을 클릭하면 예외가 발생했을 때 테스트를 종료하는 것 대신 마치 중단점처럼 테스트를 일시정지합니다.&lt;/p&gt;
&lt;h3 id=&quot;자바스크립트-실행&quot;&gt;자바스크립트 실행&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/api/commands#execute-script&quot;&gt;&lt;code&gt;execute script&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/api/commands#execute-async-script&quot;&gt;&lt;code&gt;execute async script&lt;/code&gt;&lt;/a&gt; 명령어를 통해 자바스크립트 코드를 실행할 수 있습니다.&lt;/p&gt;
&lt;h3 id=&quot;검증&quot;&gt;검증&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/api/commands#assert&quot;&gt;&lt;code&gt;assert&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/api/commands#assert-element-present&quot;&gt;&lt;code&gt;assert element present&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/api/commands#assert-checked&quot;&gt;&lt;code&gt;assert checked&lt;/code&gt;&lt;/a&gt; 등의 명령어를 통해 테스트하려 하는 대상이 제대로 존재하는지 검증할 수 있습니다. 검증에 실패하면 테스트를 종료합니다.&lt;/p&gt;
&lt;p&gt;검증 실패 시 테스트를 종료하고 싶지 않다면, &lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/api/commands#verify&quot;&gt;&lt;code&gt;verify&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/api/commands#verify-element-present&quot;&gt;&lt;code&gt;verify element present&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/api/commands#verify-checked&quot;&gt;&lt;code&gt;verify checked&lt;/code&gt;&lt;/a&gt; 등의 명령어를 사용하세요.&lt;/p&gt;
&lt;h3 id=&quot;변수&quot;&gt;변수&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/api/commands#store&quot;&gt;&lt;code&gt;store&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/api/commands#store-attribute&quot;&gt;&lt;code&gt;store attribute&lt;/code&gt;&lt;/a&gt; 등의 명령어를 통해 테스트 도중 필요한 값을 변수에 보관할 수 있습니다.&lt;/p&gt;
&lt;h3 id=&quot;제어문&quot;&gt;제어문&lt;/h3&gt;
&lt;p&gt;스프링 IDE는 &lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/api/commands#if&quot;&gt;&lt;code&gt;if&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/api/commands#while&quot;&gt;&lt;code&gt;while&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/api/commands#for-each&quot;&gt;&lt;code&gt;for each&lt;/code&gt;&lt;/a&gt;와 같이 프로그래밍 언어에서 지원하는 제어문을 제공합니다.&lt;/p&gt;
&lt;p&gt;각종 제어문에서는 조건을 검사하기 위해 자바스크립트 표현식을 요구합니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-javascript-control-flow&quot; id=&quot;fnref-javascript-control-flow&quot; data-footnote-ref=&quot;&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h3 id=&quot;다른-테스트-실행-명령&quot;&gt;다른 테스트 실행 명령&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/api/commands#run&quot;&gt;&lt;code&gt;run&lt;/code&gt;&lt;/a&gt; 명령어를 통해 다른 테스트를 실행할 수 있습니다.&lt;/p&gt;
&lt;h3 id=&quot;주석&quot;&gt;주석&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;enable-disable-command.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&#39;Enable/Disable this command&#39; 버튼을 누르거나 명령어 이름 앞에 &lt;code&gt;//&lt;/code&gt;를 붙여 명령어를 비활성화할 수 있습니다. 비활성화한 명령어는 실행되지 않습니다.&lt;/p&gt;
&lt;h3 id=&quot;타깃&quot;&gt;타깃&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;targets.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;타깃(target)은 명령어가 동작하는데 필요한 &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;이나 &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;같은 HTML 엘리먼트를 의미합니다.&lt;/p&gt;
&lt;h3 id=&quot;다중-타깃&quot;&gt;다중 타깃&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;multiple-targets.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;웹 사이트는 시간이 지남에 따라 내용이 달라지는 경우가 많습니다. &lt;a href=&quot;https://news.google.com/&quot;&gt;구글 뉴스&lt;/a&gt;의 경우, 실시간 정보를 반영하기 위해 짧은 시간을 주기로 계속 그 내용이 바뀝니다. 이외에도 다양한 이유로 내용이 변화합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;사람&lt;/strong&gt;은 이러한 웹 사이트의 변화 속에서도 버튼의 텍스트, 위치, 색상과 같은 다양한 단서를 종합하여 이전과 동일한 버튼임을 추리할 수 있습니다. 웹 사이트가 완전히 개편되지만 않는다면 말입니다.&lt;/p&gt;
&lt;p&gt;반대로 &lt;strong&gt;컴퓨터 프로그램&lt;/strong&gt;은 버튼의 텍스트, 위치, 색상과 같은 다양한 단서를 &lt;strong&gt;개별적으로&lt;/strong&gt; 사용할 수는 있으나, 사람과 달리 &lt;strong&gt;종합적으로&lt;/strong&gt; 추리하도록 하기는 어렵습니다. 추리라는 과정을 컴퓨터가 이해할 수 있는 알고리즘으로 설명하기가 까다롭기 때문입니다.&lt;/p&gt;
&lt;p&gt;셀레늄 IDE 역시 마찬가지입니다. 셀레늄 IDE는 주로 &lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Selectors&quot;&gt;CSS 선택자&lt;/a&gt;나 &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/XPath&quot;&gt;X패스&lt;/a&gt;(XPath)같은 위치 기반 단서를 이용해 같은 버튼임을 파악합니다. 물론 이 방식은 단서를 종합적으로 고려한 것이 아니라 단점이 존재합니다. 위치 기반 단서이기 때문에 웹 사이트의 디자인과 상관 없이 동일한 버튼을 타깃으로 선택할 수 있지만, 버튼의 위치 자체가 바뀌는 경우에는 무척 취약합니다. 이를 보완하기 위해 버튼의 텍스트를 이용해 같은 버튼임을 인지하기도 합니다. 어찌되었든 종합적인 추론 기능은 탑재하고 있지 않습니다.&lt;/p&gt;
&lt;p&gt;셀레늄 IDE는 이 문제를 해결하지 않습니다. 대신, 사용자가 웹 브라우저에서 수행한 동작을 기록할 때 요소를 파악할 수 있는 모든 방식을 동원해 &lt;strong&gt;다중 타깃&lt;/strong&gt;을 만들어둡니다. 그리고 그 가운데 어떤 방식을 선택할지는 사람에게 맡깁니다.&lt;/p&gt;
&lt;h3 id=&quot;타깃-선택&quot;&gt;타깃 선택&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;select-target-in-page.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&#39;Select target in page&#39; 버튼을 눌러 현재 페이지에서 다른 타깃을 선택할 수 있습니다. 이 버튼은 페이지 내의 다른 타깃을 선택하는 기능일 뿐입니다. 앞서 설명한 다중 타깃과는 무관합니다.&lt;/p&gt;
&lt;h2 id=&quot;로그&quot;&gt;로그&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;log.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;로그 탭에서는 테스트 중 명령어의 실행 시간이나 테스트의 성공 여부를 확인할 수 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;레퍼런스&quot;&gt;레퍼런스&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;reference.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;레퍼런스 탭은 선택한 명령어의 사용 방법을 안내합니다. 모든 명령어의 사용 방법을 확인하려면 &lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/api/commands&quot;&gt;Commands - Selenium IDE&lt;/a&gt;를 참고하세요.&lt;/p&gt;
&lt;h2 id=&quot;cli-selenium-side-runner&quot;&gt;CLI (&lt;code&gt;selenium-side-runner&lt;/code&gt;)&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.seleniumhq.org/selenium-ide/docs/en/introduction/command-line-runner/&quot;&gt;&lt;code&gt;selenium-side-runner&lt;/code&gt;&lt;/a&gt;는 셀레늄 IDE에서 작성한 테스트를 실행하는 CLI 도구입니다.&lt;/p&gt;
&lt;p&gt;이 CLI 도구를 이용해 테스트를 &lt;strong&gt;기록&lt;/strong&gt;하거나 &lt;strong&gt;편집&lt;/strong&gt;하는 것은 불가능합니다.&lt;/p&gt;
&lt;p&gt;셀레늄 IDE와 달리 더 많은 브라우저를 지원하며, 병렬 실행 기능도 포함합니다. 자동화된 테스트 환경을 만들 경우 셀레늄 IDE 대신 &lt;a href=&quot;https://www.seleniumhq.org/selenium-ide/docs/en/introduction/command-line-runner/&quot;&gt;&lt;code&gt;selenium-side-runner&lt;/code&gt;&lt;/a&gt;를 사용하는 것이 좋습니다.&lt;/p&gt;
&lt;p&gt;요약하자면 다음과 같습니다:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;GUI&lt;/th&gt;
&lt;th&gt;CLI&lt;/th&gt;
&lt;th&gt;&lt;code&gt;.side&lt;/code&gt; 파일&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;셀레늄 IDE&lt;/td&gt;
&lt;td&gt;✔️ 지원&lt;/td&gt;
&lt;td&gt;❌ 미지원&lt;/td&gt;
&lt;td&gt;✔️ 지원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://www.seleniumhq.org/selenium-ide/docs/en/introduction/command-line-runner/&quot;&gt;&lt;code&gt;selenium-side-runner&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;❌ 미지원&lt;/td&gt;
&lt;td&gt;✔️ 지원&lt;/td&gt;
&lt;td&gt;✔️ 지원&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;사람이 수행하는 동작 기록&lt;/th&gt;
&lt;th&gt;테스트 편집&lt;/th&gt;
&lt;th&gt;테스트 실행&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;셀레늄 IDE&lt;/td&gt;
&lt;td&gt;✔️ 지원&lt;/td&gt;
&lt;td&gt;✔️ 지원&lt;/td&gt;
&lt;td&gt;✔️ 지원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://www.seleniumhq.org/selenium-ide/docs/en/introduction/command-line-runner/&quot;&gt;&lt;code&gt;selenium-side-runner&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;❌ 미지원&lt;/td&gt;
&lt;td&gt;❌ 미지원&lt;/td&gt;
&lt;td&gt;✔️ 지원&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;지원 웹 브라우저&lt;/th&gt;
&lt;th&gt;테스트 병렬 실행&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;셀레늄 IDE&lt;/td&gt;
&lt;td&gt;크롬(Chrome), 파이어폭스(Firefox)&lt;/td&gt;
&lt;td&gt;❌ 미지원 (&lt;a href=&quot;https://www.seleniumhq.org/selenium-ide/docs/en/introduction/command-line-runner/&quot;&gt;&lt;code&gt;selenium-side-runner&lt;/code&gt;&lt;/a&gt;에서 실행 시 병렬 실행되게끔 하는 설정만 변경 가능)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://www.seleniumhq.org/selenium-ide/docs/en/introduction/command-line-runner/&quot;&gt;&lt;code&gt;selenium-side-runner&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;크롬(Chrome), 에지(Edge), 파이어폭스(Firefox), 인터넷 익스플로러(Internet Explorer), 사파리(Safari)&lt;/td&gt;
&lt;td&gt;✔️ 지원&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href=&quot;https://www.seleniumhq.org/selenium-ide/docs/en/introduction/command-line-runner/&quot;&gt;&lt;code&gt;selenium-side-runner&lt;/code&gt;&lt;/a&gt;는 버전 8 이상의 노드JS를 기반으로 합니다. 노드JS가 설치되어있지 않다면 &lt;a href=&quot;https://nodejs.org/&quot;&gt;노드JS 공식 홈페이지&lt;/a&gt;에서 설치할 수 있습니다.&lt;/p&gt;
&lt;p&gt;다음 명령어는 &lt;a href=&quot;https://www.seleniumhq.org/selenium-ide/docs/en/introduction/command-line-runner/&quot;&gt;&lt;code&gt;selenium-side-runner&lt;/code&gt;&lt;/a&gt;를 설치합니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;npm install --global selenium-side-runner
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;실제로 사용해보기에 앞서 &lt;a href=&quot;https://www.seleniumhq.org/selenium-ide/docs/en/introduction/command-line-runner/&quot;&gt;&lt;code&gt;selenium-side-runner&lt;/code&gt;&lt;/a&gt;를 웹 브라우저와 연결하는 과정이 필요합니다. 이를 위해 각 웹 브라우저에 맞는 웹드라이버를 설치해야 합니다. 웹드라이버의 설치 방법은 수동으로 웹드라이버 파일을 다운로드받는 방법과, &lt;code&gt;npm install&lt;/code&gt;을 통해 노드JS 패키지 형태로 다운로드받는 방법이 있습니다. &lt;a href=&quot;https://www.seleniumhq.org/selenium-ide/docs/en/introduction/command-line-runner/#installing-a-browser-driver&quot;&gt;Installing a browser driver - Selenium IDE&lt;/a&gt;를 참고하세요.&lt;/p&gt;
&lt;div class=&quot;markdown-alert markdown-alert-note&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;code&gt;npm install&lt;/code&gt;을 통해 노드JS 패키지 형태로 다운로드하는 경우 반드시 다운로드된 웹드라이버 &lt;strong&gt;자체&lt;/strong&gt;가 속한 디렉터리를 &lt;code&gt;PATH&lt;/code&gt; 환경 변수에 명시해야 합니다. 대부분의 웹드라이버 패키지는 &lt;code&gt;chromedriver&lt;/code&gt;같이 웹드라이버 명령어를 제공하기도 합니다만, 이것들은 자바스크립트 코드를 통해 간접적으로 접근하는 명령어이기 때문에 &lt;a href=&quot;https://www.seleniumhq.org/selenium-ide/docs/en/introduction/command-line-runner/&quot;&gt;&lt;code&gt;selenium-side-runner&lt;/code&gt;&lt;/a&gt;가 인식하지 못합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;준비가 끝났습니다. 셀레늄 IDE를 통해 작성한 &lt;code&gt;.side&lt;/code&gt; 파일을 &lt;a href=&quot;https://www.seleniumhq.org/selenium-ide/docs/en/introduction/command-line-runner/&quot;&gt;&lt;code&gt;selenium-side-runner&lt;/code&gt;&lt;/a&gt;로 실행해봅시다.&lt;/p&gt;
&lt;p&gt;다음 명령어는 크롬에서 &lt;code&gt;.side&lt;/code&gt; 파일을 실행합니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;selenium-side-runner my-project.side
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;크롬 드라이버 대신 다른 드라이버를 사용하길 원할 경우 다음과 같이 해야 합니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;selenium-side-runner --capabilities &quot;browserName=&#39;internet explorer&#39;&quot; my-project.side
selenium-side-runner --capabilities &quot;browserName=edge&quot; my-project.side
selenium-side-runner --capabilities &quot;browserName=firefox&quot; my-project.side
selenium-side-runner --capabilities &quot;browserName=safari&quot; my-project.side
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이외에도 &lt;a href=&quot;https://www.seleniumhq.org/selenium-ide/docs/en/introduction/command-line-runner/&quot;&gt;&lt;code&gt;selenium-side-runner&lt;/code&gt;&lt;/a&gt;는 다음과 같은 기능을 제공합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.seleniumhq.org/selenium-ide/docs/en/introduction/command-line-runner/#change-the-base-url&quot;&gt;베이스 URL 변경&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.seleniumhq.org/selenium-ide/docs/en/introduction/command-line-runner/#specify-a-default-configuration&quot;&gt;설정 파일 지원 (&lt;code&gt;.side.yml&lt;/code&gt;)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/introduction/command-line-runner#filter-tests&quot;&gt;정규 표현식을 통해 특정 테스트만 필터링&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.seleniumhq.org/selenium-ide/docs/en/introduction/command-line-runner/#test-parallelization-in-a-suite&quot;&gt;병렬 컴퓨팅을 위한 셀레늄 그리드(Selenium Grid) 연결&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;관련-saas&quot;&gt;관련 SaaS&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://testingbot.com/&quot;&gt;TestingBot&lt;/a&gt;: 클라우드 기반의 셀레늄 IDE&lt;/li&gt;
&lt;/ul&gt;
&lt;section class=&quot;footnotes&quot; data-footnotes=&quot;&quot;&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-electron&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/SeleniumHQ/selenium-ide#electron&quot;&gt;Electron - Selenium IDE&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The move to Electron is a work in progress. We will post updates as progress is made. If you&#39;re looking for Selenium IDE as a browser extension then check out the v3 branch.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-electron&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;1&quot; aria-label=&quot;Back to reference 1&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-why-location-not-remembered&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/introduction/faq#why-is-the-location-i-saved-my-side-project-to-not-remembered&quot;&gt;Why is the location I saved my SIDE project to not remembered? - Selenium IDE&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;All of these questions are part of the same problem -- as a browser extension Selenium IDE does not have access to the file system. The only way to offer &quot;save&quot; functionality is through downloading the file. This issue will be resolved when the IDE moves to a native application. This will give the IDE premier filesystem access, which will enable it to offer a polished &quot;save&quot; experience.&lt;/p&gt;
&lt;p&gt;If you want to stay updated, you can follow along with issue 363.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-why-location-not-remembered&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;2&quot; aria-label=&quot;Back to reference 2&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-supported-exports&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/introduction/code-export#supported-exports&quot;&gt;Code Export - Selenium IDE&lt;/a&gt; &lt;a href=&quot;#fnref-supported-exports&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;3&quot; aria-label=&quot;Back to reference 3&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-javascript-control-flow&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.selenium.dev/selenium-ide/docs/en/introduction/control-flow#javascript-expressions&quot;&gt;Control Flow - Selenium IDE&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Conditions in your application are checked by using JavaScript expressions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-javascript-control-flow&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;4&quot; aria-label=&quot;Back to reference 4&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
      <category>web</category>
      <pubDate>Sun, 14 Jun 2020 00:00:00 GMT</pubDate>
      <guid>https://www.bangseongbeom.com/selenium-ide-guide/</guid>
      
    </item>
    <item>
      <title>셀레늄 가이드</title>
      <link>https://www.bangseongbeom.com/selenium-guide</link>
      <description>&lt;h1 id=&quot;셀레늄-가이드&quot;&gt;셀레늄 가이드&lt;/h1&gt;
&lt;h2 id=&quot;셀레늄-웹드라이버-vs-셀레늄-ide&quot;&gt;셀레늄 웹드라이버 vs 셀레늄 IDE&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;인터페이스&lt;/th&gt;
&lt;th&gt;학습 난이도&lt;/th&gt;
&lt;th&gt;사람이 수행하는 동작 기록&lt;/th&gt;
&lt;th&gt;CLI&lt;/th&gt;
&lt;th&gt;변수, 함수, 제어문(&lt;code&gt;if&lt;/code&gt;, &lt;code&gt;for&lt;/code&gt;) 등&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;셀레늄 웹드라이버&lt;/td&gt;
&lt;td&gt;라이브러리&lt;/td&gt;
&lt;td&gt;👿 어려움 (프로그래밍 언어 학습 필요)&lt;/td&gt;
&lt;td&gt;❌ 미지원&lt;/td&gt;
&lt;td&gt;✔️ 지원&lt;/td&gt;
&lt;td&gt;✔️ 지원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;셀레늄 IDE&lt;/td&gt;
&lt;td&gt;GUI&lt;/td&gt;
&lt;td&gt;👼 쉬움&lt;/td&gt;
&lt;td&gt;✔️ 지원&lt;/td&gt;
&lt;td&gt;✔️ 별도 CLI 도구(&lt;a href=&quot;https://www.seleniumhq.org/selenium-ide/docs/en/introduction/command-line-runner/&quot;&gt;&lt;code&gt;selenium-side-runner&lt;/code&gt;&lt;/a&gt;)를 통해 지원&lt;/td&gt;
&lt;td&gt;✔️ 지원&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;이 글은 셀레늄 IDE를 설명합니다. 셀레늄 IDE는 GUI를 제공합니다. 이와 달리 프로그래밍 언어로 작성된 코드를 통해 조작할 수 있는 라이브러리 형태도 있습니다. 이를 가리켜 셀레늄 웹드라이버라 합니다.&lt;/p&gt;
&lt;p&gt;셀레늄 웹드라이버의 경우, 파이썬이나 자바와 같은 프로그래밍 언어를 사용하므로 자유도 높게 웹 브라우저를 조작할 수 있습니다. 반면 비개발자 입장에서는 프로그래밍 언어를 학습하는 것이 부담스럽습니다. 개발자 입장에서도 일일이 코드를 작성하는 것이 번거롭습니다.&lt;/p&gt;
&lt;p&gt;반면 &lt;strong&gt;셀레늄 IDE&lt;/strong&gt;는 사람이 웹 브라우저에서 수행한 클릭, 텍스트 입력과 같은 동작을 기록합니다. 비개발자뿐만 아니라 개발자도 편리하게 사용할 수 있습니다.&lt;/p&gt;
&lt;p&gt;기록한 동작을 GUI 없이 실행할 수 있도록 &lt;strong&gt;별도의 CLI 도구&lt;/strong&gt;(&lt;a href=&quot;https://www.seleniumhq.org/selenium-ide/docs/en/introduction/command-line-runner/&quot;&gt;&lt;code&gt;selenium-side-runner&lt;/code&gt;&lt;/a&gt;)도 제공합니다. 이를 이용해 기록한 테스트를 주기적으로 실행하거나 또는 젠킨스(Jenkins), 서클CI(CircleCI)와 같은 CI/CD 도구를 이용하여 테스트를 자동화할 수도 있습니다.&lt;/p&gt;
&lt;p&gt;셀레늄 IDE는 단순히 웹 브라우저에서 사람이 수행한 동작만을 기록하는 것이 아닙니다. &lt;strong&gt;변수, 함수, 제어문&lt;/strong&gt;과 같이 프로그래밍 언어처럼 테스트를 작성할 수 있도록 도와주는 고급 기능도 제공합니다. 이를 통해 (프로그래밍 언어만큼 자유롭지는 않지만) 어느 정도 논리적인 동작을 구성할 수 있습니다.&lt;/p&gt;
</description>
      <category>web</category>
      <pubDate>Tue, 09 Jun 2020 00:00:00 GMT</pubDate>
      <guid>https://www.bangseongbeom.com/selenium-guide</guid>
      
    </item>
    <item>
      <title>넘파이 vs 사이파이</title>
      <link>https://www.bangseongbeom.com/numpy-vs-scipy</link>
      <description>&lt;h1 id=&quot;넘파이-vs-사이파이&quot;&gt;넘파이 vs 사이파이&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://numpy.org/&quot;&gt;넘파이&lt;/a&gt;(NumPy)와 &lt;a href=&quot;https://scipy.org/&quot;&gt;사이파이&lt;/a&gt;(SciPy)의 차이점에 대해 다룹니다.&lt;/p&gt;
&lt;h2 id=&quot;주요-역할&quot;&gt;주요 역할&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;주요 역할&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://numpy.org/&quot;&gt;넘파이&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;행렬 및 관련 기초 연산&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://scipy.org/&quot;&gt;사이파이&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;수학, 과학 알고리즘&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://numpy.org/&quot;&gt;넘파이&lt;/a&gt;:&lt;/strong&gt; 행렬 및 관련 기초 연산을 지원합니다. 행렬 그 자체에 대한 지원과 더불어, 정렬이나 형태 변환과 같이 행렬에서 사용하는 기본적인 연산을 지원합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://scipy.org/&quot;&gt;사이파이&lt;/a&gt;:&lt;/strong&gt; &lt;a href=&quot;https://numpy.org/&quot;&gt;넘파이&lt;/a&gt;에서 제공하는 행렬에 기반한 수학, 과학 알고리즘을 지원합니다.&lt;/p&gt;
&lt;h2 id=&quot;fft-선형대수-알고리즘&quot;&gt;FFT, 선형대수 알고리즘&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;FFT, 선형대수 알고리즘&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://numpy.org/&quot;&gt;넘파이&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;⚠️ 하위 호환성을 위해 어느 정도의 FFT, 선형대수 알고리즘 지원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://scipy.org/&quot;&gt;사이파이&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✔️ 완전한 기능을 가진 FFT, 선형대수 알고리즘 지원&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;a href=&quot;https://numpy.org/&quot;&gt;넘파이&lt;/a&gt;의 주요 역할은 행렬과 관련된 기초 연산을 제공하는 것이므로, 원칙적으로는 FFT와 선형대수 알고리즘을 지원할 필요가 없습니다. 하지만 &lt;a href=&quot;https://numpy.org/&quot;&gt;넘파이&lt;/a&gt;의 선배격인 라이브러리에서 FFT와 선형대수를 지원해왔기에, &lt;a href=&quot;https://numpy.org/&quot;&gt;넘파이&lt;/a&gt; 역시 호환성을 위해 이러한 기능을 가지게 되었습니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-faq-scipy&quot; id=&quot;fnref-faq-scipy&quot; data-footnote-ref=&quot;&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-numpy-dual-numpy&quot; id=&quot;fnref-numpy-dual-numpy&quot; data-footnote-ref=&quot;&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;일반적인 경우라면 &lt;a href=&quot;https://numpy.org/&quot;&gt;넘파이&lt;/a&gt; 대신 &lt;a href=&quot;https://scipy.org/&quot;&gt;사이파이&lt;/a&gt;에 있는 FFT, 선형대수 알고리즘을 사용하는 것이 좋습니다. 대부분의 새로운 기능은 &lt;a href=&quot;https://scipy.org/&quot;&gt;사이파이&lt;/a&gt;에서만 제공하기 때문입니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-faq-scipy&quot; id=&quot;fnref-faq-scipy-2&quot; data-footnote-ref=&quot;&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-numpy-dual-numpy&quot; id=&quot;fnref-numpy-dual-numpy-2&quot; data-footnote-ref=&quot;&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h2 id=&quot;알고리즘의-포트란-의존성&quot;&gt;알고리즘의 포트란 의존성&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;알고리즘의 포트란 의존성&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://numpy.org/&quot;&gt;넘파이&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;❌ 포트란에 의존하지 않음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://scipy.org/&quot;&gt;사이파이&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✔️ FFT, 선형대수뿐만 아니라 많은 알고리즘이 포트란에 의존&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;a href=&quot;https://numpy.org/&quot;&gt;넘파이&lt;/a&gt;에서 제공하는 FFT와 선형대수 알고리즘의 또다른 특징은 포트란에 의존하지 않는다는 것입니다. 이와 반대로 &lt;a href=&quot;https://scipy.org/&quot;&gt;사이파이&lt;/a&gt;에서 제공하는 많은 알고리즘은 포트란에 강력히 의존하고 있으며, 이는 FFT와 선형대수 역시 마찬가지입니다. &lt;a href=&quot;https://scipy.org/&quot;&gt;사이파이&lt;/a&gt;에서 선형대수 알고리즘을 제공하는 &lt;code&gt;scipy.linalg&lt;/code&gt; 모듈은 포트란으로 짜여진 &lt;a href=&quot;http://www.netlib.org/lapack/&quot;&gt;LAPACK&lt;/a&gt; 라이브러리를 파이썬에서 사용할 수 있게끔 감싸놓은 것입니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-wrapping-of-fortran-lapack-scipy&quot; id=&quot;fnref-wrapping-of-fortran-lapack-scipy&quot; data-footnote-ref=&quot;&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h2 id=&quot;참고&quot;&gt;참고&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/6200910/relationship-between-scipy-and-numpy&quot;&gt;Relationship between SciPy and NumPy - Stack Overflow&lt;/a&gt;: 관련 스택오버플로 질문&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/6363154/what-is-the-difference-between-numpy-fft-and-scipy-fftpack&quot;&gt;What is the difference between numpy.fft and scipy.fftpack? - Stack Overflow&lt;/a&gt;: 관련 스택오버플로 질문&lt;/li&gt;
&lt;/ul&gt;
&lt;section class=&quot;footnotes&quot; data-footnotes=&quot;&quot;&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-faq-scipy&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.scipy.org/scipylib/faq.html#what-is-the-difference-between-numpy-and-scipy&quot;&gt;Frequently Asked Questions - SciPy&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What is the difference between NumPy and SciPy?&lt;/p&gt;
&lt;p&gt;In an ideal world, NumPy would contain nothing but the array data type and the most basic operations: indexing, sorting, reshaping, basic elementwise functions, etc. All numerical code would reside in SciPy. However, one of NumPy’s important goals is compatibility, so NumPy tries to retain all features supported by either of its predecessors. Thus, NumPy contains some linear algebra functions and Fourier transforms, even though these more properly belong in SciPy. In any case, SciPy contains more fully-featured versions of the linear algebra modules, as well as many other numerical algorithms. If you are doing scientific computing with Python, you should probably install both NumPy and SciPy. Most new features belong in SciPy rather than NumPy.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-faq-scipy&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;1&quot; aria-label=&quot;Back to reference 1&quot;&gt;↩&lt;/a&gt; &lt;a href=&quot;#fnref-faq-scipy-2&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;1-2&quot; aria-label=&quot;Back to reference 1-2&quot;&gt;↩&lt;sup class=&quot;footnote-ref&quot;&gt;2&lt;/sup&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-numpy-dual-numpy&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://numpy.org/doc/stable/reference/routines.dual.html&quot;&gt;Optionally Scipy-accelerated routines (numpy.dual) - NumPy&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Scipy can be built to use accelerated or otherwise improved libraries for FFTs, linear algebra, and special functions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-numpy-dual-numpy&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;2&quot; aria-label=&quot;Back to reference 2&quot;&gt;↩&lt;/a&gt; &lt;a href=&quot;#fnref-numpy-dual-numpy-2&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;2-2&quot; aria-label=&quot;Back to reference 2-2&quot;&gt;↩&lt;sup class=&quot;footnote-ref&quot;&gt;2&lt;/sup&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-wrapping-of-fortran-lapack-scipy&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.scipy.org/scipylib/faq.html#why-both-numpy-linalg-and-scipy-linalg-what-s-the-difference&quot;&gt;Frequently Asked Questions - SciPy&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Why both numpy.linalg and scipy.linalg? What’s the difference?&lt;/p&gt;
&lt;p&gt;scipy.linalg is a more complete wrapping of Fortran LAPACK using f2py.&lt;/p&gt;
&lt;p&gt;One of the design goals of NumPy was to make it buildable without a Fortran compiler, and if you don’t have LAPACK available, NumPy will use its own implementation. SciPy requires a Fortran compiler to be built, and heavily depends on wrapped Fortran code.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-wrapping-of-fortran-lapack-scipy&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;3&quot; aria-label=&quot;Back to reference 3&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
      <category>machine-learning</category>
      <pubDate>Sun, 17 May 2020 00:00:00 GMT</pubDate>
      <guid>https://www.bangseongbeom.com/numpy-vs-scipy</guid>
      
    </item>
    <item>
      <title>기계 학습 라이브러리들의 &#39;import as&#39; 약칭</title>
      <link>https://www.bangseongbeom.com/machine-learning-libraries-import-as-abbreviations</link>
      <description>&lt;h1 id=&quot;기계-학습-라이브러리들의-import-as-약칭&quot;&gt;기계 학습 라이브러리들의 &#39;import as&#39; 약칭&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;numpy&lt;/code&gt;를 &lt;code&gt;np&lt;/code&gt;로 줄여쓰는 것처럼, 다양한 기계 학습 라이브러리의 약칭을 정리했습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;수학이나 통계, 기계 학습과 관련된 파이썬 환경에서는, 라이브러리의 모듈 전체를 한꺼번에 &lt;code&gt;import&lt;/code&gt;하는 것을 선호합니다. 가져올 함수는 많은데 이것들을 하나 하나 &lt;code&gt;import&lt;/code&gt;하는 건 여간 귀찮은 일이 아닙니다.&lt;/p&gt;
&lt;p&gt;아예 &lt;a href=&quot;https://numpy.org/&quot;&gt;넘파이&lt;/a&gt;(NumPy)는 공식 문서에서 &lt;code&gt;import as&lt;/code&gt;를 어떻게 할 것인지 대해 명시적으로 언급합니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-import-conventions-throughout-numpy&quot; id=&quot;fnref-import-conventions-throughout-numpy&quot; data-footnote-ref=&quot;&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. 이와 관련된 논의 또한 오래 전부터 존재해왔습니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-digest-vol-19-issue-44&quot; id=&quot;fnref-digest-vol-19-issue-44&quot; data-footnote-ref=&quot;&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;import as&lt;/code&gt;를 어떻게 할 것인지는 전적으로 &lt;strong&gt;코드 작성자의 선택&lt;/strong&gt;입니다. 하지만 관습적으로 쓰이는 약칭을 사용한다면, 다른 사람이 나의 코드를 볼 때 내 코드의 &lt;code&gt;import&lt;/code&gt;가 어떻게 되어있는지 굳이 확인해보지 않아도 된다는 장점이 있습니다. 기계 학습 관련 라이브러리 중 하나인 &lt;a href=&quot;https://pandas.pydata.org/&quot;&gt;판다스&lt;/a&gt;(pandas)는 문서의 모든 예시 코드에서 &lt;code&gt;import pandas as pd&lt;/code&gt; 코드가 삽입되어 있다고 가정합니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-code-assumed-pandas&quot; id=&quot;fnref-code-assumed-pandas&quot; data-footnote-ref=&quot;&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;. 때문에 &lt;code&gt;pd&lt;/code&gt;가 무엇의 약칭인지 일일이 확인할 필요가 없습니다.&lt;/p&gt;
&lt;h2 id=&quot;넘파이&quot;&gt;넘파이&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://numpy.org/&quot;&gt;넘파이&lt;/a&gt;의 경우, 공식 문서와 소스 코드에서 &lt;code&gt;numpy&lt;/code&gt; 모듈을 &lt;code&gt;np&lt;/code&gt;로 줄여쓸 것이라 &lt;strong&gt;명시적으로&lt;/strong&gt; 언급합니다:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://numpy.org/doc/stable/docs/howto_document.html#import-conventions&quot;&gt;A Guide to NumPy/SciPy Documentation - NumPy&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The following import conventions are used throughout the NumPy source and documentation:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;import numpy as np
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;맷플롯립&quot;&gt;맷플롯립&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://numpy.org/&quot;&gt;넘파이&lt;/a&gt; 공식 문서와 소스 코드에서는 &lt;a href=&quot;https://matplotlib.org/&quot;&gt;맷플롯립&lt;/a&gt;(Matplotlib)의 &lt;code&gt;matplotlib&lt;/code&gt; 모듈을 &lt;code&gt;mpl&lt;/code&gt;, &lt;code&gt;matplotlib.pyplot&lt;/code&gt; 모듈을 &lt;code&gt;plt&lt;/code&gt;으로 줄여쓸 것이라 &lt;strong&gt;명시적으로&lt;/strong&gt; 언급합니다:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://numpy.org/doc/stable/docs/howto_document.html#import-conventions&quot;&gt;A Guide to NumPy/SciPy Documentation - NumPy&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The following import conventions are used throughout the NumPy source and documentation:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;import matplotlib as mpl
import matplotlib.pyplot as plt
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://matplotlib.org/&quot;&gt;맷플롯립&lt;/a&gt;의 다른 하위 모듈에 대한 약칭에 대해서는 명시적으로 언급하고 있지 않습니다. 공식 문서를 살펴보면 모듈 자체의 이름을 사용하거나, 아니면 모듈에서 사용할 함수나 클래스를 하나씩 &lt;code&gt;from import&lt;/code&gt;로 가져옵니다:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://matplotlib.org/faq/howto_faq.html&quot;&gt;How-to - Matplotlib&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;import matplotlib.mlab as mlab
import matplotlib.ticker as ticker
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;...&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;from matplotlib.backends.backend_pdf import PdfPages
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;...&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;from matplotlib.figure import Figure
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;사이파이&quot;&gt;사이파이&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://scipy.org/&quot;&gt;사이파이&lt;/a&gt;(SciPy)의 경우 &lt;code&gt;scipy&lt;/code&gt; 모듈에 대해 약칭을 사용하지 않을 것을 &lt;strong&gt;명시적으로&lt;/strong&gt; 권고합니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-do-not-abbreviate-scipy&quot; id=&quot;fnref-do-not-abbreviate-scipy&quot; data-footnote-ref=&quot;&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;. 하위 모듈에 대해 각각 &lt;code&gt;from import&lt;/code&gt;를 사용합니다:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.scipy.org/doc/scipy/reference/tutorial/general.html#scipy-organization&quot;&gt;Introduction - SciPy&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;SciPy sub-packages need to be imported separately, for example:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;&amp;gt;&amp;gt;&amp;gt; from scipy import linalg, optimize
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;다만 &lt;code&gt;scipy.io&lt;/code&gt; 모듈은 파이썬 내장 패키지인 &lt;code&gt;io&lt;/code&gt;와 충돌하기에, &lt;code&gt;import scipy.io as spio&lt;/code&gt;처럼 약칭을 사용하는 것으로 보입니다:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.scipy.org/doc/scipy/reference/api.html#guidelines-for-importing-functions-from-scipy&quot;&gt;SciPy API - SciPy&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This form of importing submodules is preferred for all submodules except scipy.io (because io is also the name of a module in the Python stdlib):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;from scipy import interpolate
from scipy import integrate
import scipy.io as spio
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;scipy.sparse.linalg&lt;/code&gt; 모듈같이 한 층 더 깊이 존재하는 모듈이라면 &lt;code&gt;from scipy.sparse import linalg&lt;/code&gt;처럼 합니다:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.scipy.org/doc/scipy/reference/api.html#guidelines-for-importing-functions-from-scipy&quot;&gt;SciPy API - SciPy&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;# second form
from scipy.stats import distributions
distributions.lomax(...)
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;markdown-alert markdown-alert-note&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Note&lt;/p&gt;
&lt;p&gt;지금은 더 이상 &lt;code&gt;scipy&lt;/code&gt; 모듈 자체를 &lt;code&gt;import&lt;/code&gt;하는 것을 권장하지 않지만&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-api-scipy&quot; id=&quot;fnref-api-scipy&quot; data-footnote-ref=&quot;&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;, 예전에는 &lt;code&gt;scipy&lt;/code&gt;를 직접 &lt;code&gt;import&lt;/code&gt;하고 했습니다. 당시에는 &lt;code&gt;scipy&lt;/code&gt; 모듈 자체에 대해 &lt;code&gt;sp&lt;/code&gt;라는 약칭을 사용하기도 했던 것으로 보입니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-top-level-scipy&quot; id=&quot;fnref-top-level-scipy&quot; data-footnote-ref=&quot;&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;판다스&quot;&gt;판다스&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://pandas.pydata.org/&quot;&gt;판다스&lt;/a&gt;(pandas)의 경우 명시적으로 언급하지는 않으나, 공식 문서에서는 &lt;code&gt;pandas&lt;/code&gt; 모듈을 &lt;code&gt;pd&lt;/code&gt;라고 줄여씁니다:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://pandas.pydata.org/docs/development/contributing_docstring.html#conventions-for-the-examples&quot;&gt;pandas docstring guide - pandas&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Code in examples is assumed to always start with these two lines which are not shown:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;import numpy as np
import pandas as pd
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;사이킷런&quot;&gt;사이킷런&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://scikit-learn.org/&quot;&gt;사이킷런&lt;/a&gt;(scikit-learn)의 경우 명시적으로 언급하지는 않으나, 공식 문서에서는 &lt;code&gt;import as&lt;/code&gt; 대신 &lt;code&gt;from import&lt;/code&gt;로 모듈, 함수, 클래스를 적절하게 불러옵니다:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://scikit-learn.org/stable/auto_examples/bicluster/plot_spectral_coclustering.html&quot;&gt;A demo of the Spectral Co-Clustering algorithm - scikit-learn&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;from sklearn.datasets import make_biclusters
from sklearn.cluster import SpectralCoclustering
from sklearn.metrics import consensus_score
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://scikit-learn.org/stable/tutorial/basic/tutorial.html&quot;&gt;An introduction to machine learning with scikit-learn - scikit-learn&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;&amp;gt;&amp;gt;&amp;gt; from sklearn import datasets
&amp;gt;&amp;gt;&amp;gt; from sklearn import svm
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;대스크&quot;&gt;대스크&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://dask.org/&quot;&gt;대스크&lt;/a&gt;(Dask)의 경우 명시적으로 언급하지는 않으나, 공식 문서에서는 &lt;code&gt;dask.dataframe&lt;/code&gt; 모듈을 &lt;code&gt;dd&lt;/code&gt;로, &lt;code&gt;dask.array&lt;/code&gt; 모듈을 &lt;code&gt;da&lt;/code&gt;로, &lt;code&gt;dask.bag&lt;/code&gt; 모듈을 &lt;code&gt;db&lt;/code&gt;로 줄여씁니다:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.dask.org/en/latest/&quot;&gt;Dask - Dask&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;import dask.dataframe as dd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;...&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;import dask.array as da
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;...&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;import dask.bag as db
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;그 외 모듈의 경우 &lt;code&gt;from import&lt;/code&gt;를 통해 함수나 클래스를 직접 가져오는 것으로 보입니다:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.dask.org/en/latest/futures.html&quot;&gt;Futures - Dask&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;from dask.distributed import Client
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;...&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;from dask.distributed import wait
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;텐서플로&quot;&gt;텐서플로&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.tensorflow.org/&quot;&gt;탠서플로&lt;/a&gt;(TensorFlow)의 경우 명시적으로 언급하지는 않으나, 공식 문서에서는 &lt;code&gt;tensorflow&lt;/code&gt; 모듈을 &lt;code&gt;tf&lt;/code&gt;로 줄여씁니다:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.tensorflow.org/tutorials/quickstart/beginner&quot;&gt;TensorFlow 2 quickstart for beginners - TensorFlow&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;import tensorflow as tf
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;tensorflow_datasets&lt;/code&gt; 모듈의 경우 &lt;code&gt;tfds&lt;/code&gt;로 줄여씁니다:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.tensorflow.org/datasets/overview&quot;&gt;TensorFlow Datasets - TensorFlow&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;import tensorflow_datasets as tfds
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;파이토치&quot;&gt;파이토치&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://pytorch.org/&quot;&gt;파이토치&lt;/a&gt;(PyTorch)의 경우 명시적으로 언급하지는 않으나, 공식 문서에서는 &lt;code&gt;import torch&lt;/code&gt;를 주로 사용합니다. 하위 모듈이나 함수, 클래스의 경우 이름이 짧으면 그대로 쓰고 이름이 길면 줄여 쓰는 경향이 있습니다:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://pytorch.org/get-started/locally/&quot;&gt;Start Locally - PyTorch&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;import torch
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://pytorch.org/docs/stable/notes/ddp.html&quot;&gt;Distributed Data Parallel - PyTorch&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;import torch.distributed as dist
import torch.multiprocessing as mp
import torch.nn as nn
import torch.optim as optim
from torch.nn.parallel import DistributedDataParallel as DDP
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;케라스&quot;&gt;케라스&lt;/h2&gt;
&lt;p&gt;[케라스](Keras)의 경우 명시적으로 언급하지는 않으나, 공식 문서에서는 &lt;code&gt;keras&lt;/code&gt;는 &lt;code&gt;keras&lt;/code&gt; 그대로 사용합니다. &lt;code&gt;keras.layers&lt;/code&gt;의 경우 &lt;code&gt;layers&lt;/code&gt;로 줄여쓰거나 &lt;code&gt;keras.layers&lt;/code&gt; 그대로 사용합니다:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://keras.io/guides/functional_api/&quot;&gt;The Functional API - Keras&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;from tensorflow import keras
from tensorflow.keras import layers
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://keras.io/guides/serialization_and_saving/&quot;&gt;Serialization and saving - Keras&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;outputs = keras.layers.Dense(1)(inputs)
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;section class=&quot;footnotes&quot; data-footnotes=&quot;&quot;&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-import-conventions-throughout-numpy&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://numpy.org/doc/stable/docs/howto_document.html#import-conventions&quot;&gt;A Guide to NumPy/SciPy Documentation - NumPy&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The following import conventions are used throughout the NumPy source and documentation:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-import-conventions-throughout-numpy&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;1&quot; aria-label=&quot;Back to reference 1&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-digest-vol-19-issue-44&quot;&gt;
&lt;p&gt;&lt;a href=&quot;http://numpy-discussion.10968.n7.nabble.com/Re-Numpy-discussion-Digest-Vol-19-Issue-44-tt10095.html&quot;&gt;Re: Numpy-discussion Digest, Vol 19, Issue 44&lt;/a&gt;: 2008년 메일링 리스트에서 진행된 &lt;code&gt;import as&lt;/code&gt; 표준화 논의 &lt;a href=&quot;#fnref-digest-vol-19-issue-44&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;2&quot; aria-label=&quot;Back to reference 2&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-code-assumed-pandas&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://pandas.pydata.org/docs/development/contributing_docstring.html#conventions-for-the-examples&quot;&gt;pandas docstring guide - pandas&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Code in examples is assumed to always start with these two lines which are not shown:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;import numpy as np
import pandas as pd
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-code-assumed-pandas&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;3&quot; aria-label=&quot;Back to reference 3&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-do-not-abbreviate-scipy&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://numpy.org/doc/stable/docs/howto_document.html#import-conventions&quot;&gt;A Guide to NumPy/SciPy Documentation - NumPy&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Do not abbreviate scipy. There is no motivating use case to abbreviate it in the real world, so we avoid it in the documentation to avoid confusion.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-do-not-abbreviate-scipy&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;4&quot; aria-label=&quot;Back to reference 4&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-api-scipy&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.scipy.org/doc/scipy/reference/api.html&quot;&gt;SciPy API - SciPy&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;These functions still exist for backwards compatibility, but should be imported from numpy directly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-api-scipy&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;5&quot; aria-label=&quot;Back to reference 5&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-top-level-scipy&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.scipy.org/doc/scipy-0.9.0/reference/tutorial/basic.html&quot;&gt;Basic functions in Numpy (and top-level scipy) - SciPy v0.9&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To begin with, all of the Numpy functions have been subsumed into the scipy namespace so that all of those functions are available without additionally importing Numpy. In addition, the universal functions (addition, subtraction, division) have been altered to not raise exceptions if floating-point errors are encountered; instead, NaN’s and Inf’s are returned in the arrays. To assist in detection of these events, several functions (sp.isnan, sp.isfinite, sp.isinf) are available.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-top-level-scipy&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;6&quot; aria-label=&quot;Back to reference 6&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
      <category>machine-learning</category>
      <pubDate>Sun, 10 May 2020 00:00:00 GMT</pubDate>
      <guid>https://www.bangseongbeom.com/machine-learning-libraries-import-as-abbreviations</guid>
      
    </item>
    <item>
      <title>Machine learning</title>
      <link>https://www.bangseongbeom.com/machine-learning</link>
      <description>&lt;h1 id=&quot;machine-learning&quot;&gt;Machine learning&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/machine-learning-libraries-import-as-abbreviations&quot;&gt;기계 학습 라이브러리들의 &#39;import as&#39; 약칭&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/numpy-vs-scipy&quot;&gt;넘파이 vs 사이파이&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
      <category>machine-learning</category>
      <pubDate>Fri, 08 May 2020 16:12:55 GMT</pubDate>
      <guid>https://www.bangseongbeom.com/machine-learning</guid>
      
    </item>
    <item>
      <title>발레나에처 소개</title>
      <link>https://www.bangseongbeom.com/balena-etcher-intro/</link>
      <description>&lt;h1 id=&quot;발레나에처-소개&quot;&gt;발레나에처 소개&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://www.balena.io/etcher/&quot;&gt;발레나에처&lt;/a&gt;(balenaEtcher)는 간단하게 SD 카드나 USB에 운영 체제 이미지를 구울 수 있는 유틸리티 프로그램입니다.&lt;/p&gt;
&lt;h2 id=&quot;장점&quot;&gt;장점&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;매우 단순한 UI를 가지고 있어 누구나 쉽게 사용할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;단점&quot;&gt;단점&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;용량이 100MB가 넘습니다. 기능에 비해 너무 큽니다. (이는 &lt;a href=&quot;https://www.electronjs.org/&quot;&gt;일렉트론&lt;/a&gt;을 기반으로 하기 때문입니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-electron&quot; id=&quot;fnref-electron&quot; data-footnote-ref=&quot;&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. 일렉트론은 내부적으로 &lt;a href=&quot;https://www.google.com/chrome/&quot;&gt;크롬 브라우저&lt;/a&gt;를 포함하고 있습니다)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;시스템-요구-사항&quot;&gt;시스템 요구 사항&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;언어:&lt;/strong&gt; 영어 &lt;strong&gt;(한국어 지원 안 함)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OS:&lt;/strong&gt; 윈도우, 맥OS, 리눅스&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;용량:&lt;/strong&gt; 약 142MB&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;사용-방법&quot;&gt;사용 방법&lt;/h2&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;balena-etcher-1.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;strong&gt;&#39;Select image&#39;&lt;/strong&gt; 버튼을 누릅니다.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;balena-etcher-2.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;굽는데 사용할 이미지 파일(ISO, IMG, ...)을 선택합니다.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;balena-etcher-3.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;strong&gt;&#39;Select target&#39;&lt;/strong&gt; 버튼을 누릅니다.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;balena-etcher-4.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;이미지를 설치할 SD 카드 또는 USB를 선택합니다.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;balena-etcher-5.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;strong&gt;&#39;Flash!&#39;&lt;/strong&gt; 버튼을 눌러 굽기를 시작합니다.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;balena-etcher-6.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;SD 카드 또는 USB의 용량이 너무 클 경우, &lt;a href=&quot;https://www.balena.io/etcher/&quot;&gt;발레나에처&lt;/a&gt;는 사용자가 &lt;strong&gt;자료 백업 용과 같은 중요한 드라이브&lt;/strong&gt;에 이미지를 구우려 하는 것이 아닌지 경고합니다. 정말 이미지를 굽기 위한 드라이브가 맞다면 &lt;strong&gt;&#39;Continue&#39;&lt;/strong&gt; 버튼을 눌러 굽기를 시작합시다.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;대안&quot;&gt;대안&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://rufus.ie/&quot;&gt;루퍼스&lt;/a&gt;(Rufus): 매우 적은 용량을 차지합니다. 한국어도 지원합니다. 단순한 UI를 가지고 있지만, 미숙련 사용자에게는 &lt;a href=&quot;https://www.balena.io/etcher/&quot;&gt;발레나에처&lt;/a&gt;에 비해 조금 어려울 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;section class=&quot;footnotes&quot; data-footnotes=&quot;&quot;&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-electron&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.balena.io/etcher/&quot;&gt;balenaEtcher&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Open Source&lt;/p&gt;
&lt;p&gt;Made with JS, HTML, node.js and Electron. Dive in and contribute!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-electron&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;1&quot; aria-label=&quot;Back to reference 1&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
      <category>misc</category>
      <pubDate>Thu, 07 May 2020 00:00:00 GMT</pubDate>
      <guid>https://www.bangseongbeom.com/balena-etcher-intro/</guid>
      
    </item>
    <item>
      <title>Misc.</title>
      <link>https://www.bangseongbeom.com/misc</link>
      <description>&lt;h1 id=&quot;misc&quot;&gt;Misc.&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/balena-etcher-intro/&quot;&gt;발레나에처 소개&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
      <category>misc</category>
      <pubDate>Wed, 06 May 2020 18:37:25 GMT</pubDate>
      <guid>https://www.bangseongbeom.com/misc</guid>
      
    </item>
    <item>
      <title>배시 배열</title>
      <link>https://www.bangseongbeom.com/bash-arrays</link>
      <description>&lt;h1 id=&quot;배시-배열&quot;&gt;배시 배열&lt;/h1&gt;
&lt;p&gt;배열을 통해 여러 값을 효과적으로 다룰 수 있습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/index.html&quot;&gt;배시&lt;/a&gt;(Bash)는 여느 프로그래밍 언어와 같이 배열 기능을 제공합니다. 배열은 여러 값을 하나의 변수에 보관할 수 있도록 해줍니다. 새로운 값을 추가하거나 이미 존재하는 값을 수정 또는 삭제할 수 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;배열-생성&quot;&gt;배열 생성&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;변수이름=(값1 값2 값3)&lt;/code&gt; 형태로 배열을 생성합니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-way-1&quot; id=&quot;fnref-way-1&quot; data-footnote-ref=&quot;&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. &lt;strong&gt;배열의 값을 띄어쓰기로 구분함에 주의하세요.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF=(100 200 Hello)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;공백을 포함한 문자열&lt;/strong&gt;은 [배시]의 문법 상 큰따옴표나 작은따옴표로 묶어야 합니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF=(&quot;H e l l o&quot; &#39;w o r l d&#39;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;다른 프로그래밍 언어와 달리, 배시에서는 &lt;code&gt;=&lt;/code&gt; 좌우에 띄어쓰기가 있으면 안 됩니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF = (100 200 Hello) # 잘못됨!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위 코드를 실행하면 다음과 같이 오류를 출력합니다:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-bash: syntax error near unexpected token `(&#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;값-얻기-인덱스&quot;&gt;값 얻기, 인덱스&lt;/h2&gt;
&lt;p&gt;배열로부터 값을 하나 얻기 위해서는 &lt;code&gt;${변수이름[인덱스]}&lt;/code&gt; 형태를 사용합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;인덱스&lt;/strong&gt;는 값이 배열의 어디에 위치해있는지를 가리키는 수입니다. 배열을 만들 때 나열한 순서대로 인덱스가 지정됩니다. 인덱스가 &lt;strong&gt;0&lt;/strong&gt;이라면 &lt;strong&gt;1번째&lt;/strong&gt; 값을, 인덱스가 &lt;strong&gt;1&lt;/strong&gt;이라면 &lt;strong&gt;2번째&lt;/strong&gt; 값을 의미합니다. (인덱스는 1이 아니라 &lt;strong&gt;0부터 시작&lt;/strong&gt;합니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-starts-at-zero&quot; id=&quot;fnref-starts-at-zero&quot; data-footnote-ref=&quot;&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;)&lt;/p&gt;
&lt;p&gt;다음은 배열에 &lt;code&gt;100&lt;/code&gt;, &lt;code&gt;200&lt;/code&gt;, &lt;code&gt;300&lt;/code&gt;을 넣은 뒤 순서대로 출력하는 코드입니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF=(100 200 300)

echo ${ASDF[0]}
echo ${ASDF[1]}
echo ${ASDF[2]}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;출력 결과:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;100
200
300
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;특이한-성질-중괄호가-필요한-이유&quot;&gt;[특이한 성질] 중괄호가 필요한 이유&lt;/h3&gt;
&lt;p&gt;값을 얻기 위해서는 &lt;code&gt;echo ${ASDF[2]}&lt;/code&gt;처럼 중괄호를 &lt;strong&gt;반드시&lt;/strong&gt; 붙여야 합니다. &lt;code&gt;echo $ASDF[2]&lt;/code&gt;처럼 중괄호를 붙이지 않으면, 배시는 &lt;code&gt;ASDF[2]&lt;/code&gt;를 통째로 변수로서 인식하지 않고 &lt;code&gt;ASDF&lt;/code&gt;까지만 인식합니다.&lt;/p&gt;
&lt;p&gt;그 이유는 대괄호가 특별한 값으로 먼저 취급되기 때문입니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-braces-are-required&quot; id=&quot;fnref-braces-are-required&quot; data-footnote-ref=&quot;&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;. 대괄호 없이 &lt;code&gt;$ASDF[2]&lt;/code&gt;처럼 한다면 배시는 &lt;code&gt;$ASDF&lt;/code&gt;와 &lt;code&gt;[2]&lt;/code&gt;로 나누어 인식합니다.&lt;/p&gt;
&lt;div class=&quot;markdown-alert markdown-alert-note&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;code&gt;echo $ASDF[2]&lt;/code&gt;처럼 한다고 해서 오류가 발생하지는 않습니다. 이는 배시에서 &lt;code&gt;$ASDF&lt;/code&gt;같이 &lt;strong&gt;배열 이름 자체에 접근&lt;/strong&gt;하는 것을 허용하고 있기 때문인데요, 자세한 내용은 잠시 뒤에 알아보겠습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;전체-값-얻기&quot;&gt;전체 값 얻기&lt;/h2&gt;
&lt;p&gt;전체 값을 얻는 방법은 다음과 같이 4가지 형태가 있습니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-at-or-asterisk&quot; id=&quot;fnref-at-or-asterisk&quot; data-footnote-ref=&quot;&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;${변수이름[@]}&lt;/code&gt;: 인덱스가 들어갈 자리에 &lt;code&gt;@&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;${변수이름[*]}&lt;/code&gt;: 인덱스가 들어갈 자리에 &lt;code&gt;*&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&quot;${변수이름[@]}&quot;&lt;/code&gt;: 큰따옴표(&lt;code&gt;&quot;&quot;&lt;/code&gt;)로 묶은 뒤 인덱스가 들어갈 자리에 &lt;code&gt;@&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&quot;${변수이름[*]}&quot;&lt;/code&gt;: 큰따옴표(&lt;code&gt;&quot;&quot;&lt;/code&gt;)로 묶은 뒤 인덱스가 들어갈 자리에 &lt;code&gt;*&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;다음과 같은 배열이 존재한다고 했을 때:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF[0]=&quot;A A&quot;
ASDF[1]=&quot;B   B&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;각 형태 별로 다양한 결과를 보입니다:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;명령어&lt;/th&gt;
&lt;th&gt;중간 결과&lt;/th&gt;
&lt;th&gt;출력&lt;/th&gt;
&lt;th&gt;공백&lt;/th&gt;
&lt;th&gt;위험성&lt;/th&gt;
&lt;th&gt;특징&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;echo ${ASDF[@]}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;echo A A B   B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A A B B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;무시됨&lt;/td&gt;
&lt;td&gt;⚠️ 존재&lt;/td&gt;
&lt;td&gt;하나의 값에서 공백으로 구분된 각 부분을 개별적인 문자열로서 취급&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;echo ${ASDF[*]}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;echo A A B   B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A A B B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;무시됨&lt;/td&gt;
&lt;td&gt;⚠️ 존재&lt;/td&gt;
&lt;td&gt;하나의 값에서 공백으로 구분된 각 부분을 개별적인 문자열로서 취급&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;echo &quot;${ASDF[@]}&quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;echo &quot;A A&quot; &quot;B   B&quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A A B   B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;보존됨&lt;/td&gt;
&lt;td&gt;없음&lt;/td&gt;
&lt;td&gt;각 값을 개별적인 문자열로서 취급&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;echo &quot;${ASDF[*]}&quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;echo &quot;A A B   B&quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A A B   B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;보존됨&lt;/td&gt;
&lt;td&gt;⚠️ 존재&lt;/td&gt;
&lt;td&gt;배열에 존재하는 모든 값을 하나의 문자열로서 취급&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&quot;markdown-alert markdown-alert-note&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Note&lt;/p&gt;
&lt;p&gt;배시는 개별적으로 취급하는 문자열과 문자열 사이의 공백을 하나로 합치는 성질이 있습니다. 이 성질에 관해서는...&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;결론 1:&lt;/strong&gt; 배열의 값에 공백이 들어가지 않음을 보장할 수 있다면 &lt;code&gt;echo ${ASDF[@]}&lt;/code&gt;나 &lt;code&gt;echo ${ASDF[*]}&lt;/code&gt;을 사용해도 무방합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;결론 2:&lt;/strong&gt; 그렇지 않고 얼마든지 공백이 들어갈 수 있다면 각 값을 개별적인 문자열로서 취급하는 &lt;code&gt;echo &quot;${ASDF[@]}&quot;&lt;/code&gt; 형태를 사용해야 합니다.&lt;/p&gt;
&lt;h2 id=&quot;값-변경-및-추가&quot;&gt;값 변경 및 추가&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;변수이름[인덱스]=값&lt;/code&gt; 형태로 특정 인덱스에 존재하는 값을 변경합니다. 인덱스에 값이 존재하지 않는다면 새 값을 추가합니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-way-2&quot; id=&quot;fnref-way-2&quot; data-footnote-ref=&quot;&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;다음은 배열에 &lt;code&gt;100&lt;/code&gt;, &lt;code&gt;200&lt;/code&gt;, &lt;code&gt;300&lt;/code&gt;을 넣은 뒤, &lt;code&gt;100&lt;/code&gt;을 &lt;code&gt;99999&lt;/code&gt;로 &lt;strong&gt;변경&lt;/strong&gt;하는 코드입니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF=(100 200 300)
ASDF[0]=99999
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;다음은 &lt;code&gt;Hello&lt;/code&gt;라는 값 하나만 들어간 배열을 만든 뒤, 여기에 &lt;code&gt;Linus&lt;/code&gt;와 &lt;code&gt;Torvalds&lt;/code&gt;를 &lt;strong&gt;추가&lt;/strong&gt;하는 코드입니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF=(Hello)
ASDF[1]=Linus
ASDF[2]=Torvalds
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;공백을 포함한 문자열&lt;/strong&gt;은 [배시]의 문법 상 큰따옴표나 작은따옴표로 묶어야 합니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF[0]=&quot;Brian Fox&quot;
ASDF[1]=&#39;Stephen Bourne&#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;특이한-성질-암시적-배열-생성&quot;&gt;[특이한 성질] 암시적 배열 생성&lt;/h2&gt;
&lt;p&gt;다른 프로그래밍 언어와 달리 [배시]는 배열이 존재하지 않아도 해당 변수에 값을 추가할 수 있습니다. &lt;strong&gt;변수가 배열이 아니라면 배시는 이를 배열로 만듭니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-created-automatically&quot; id=&quot;fnref-created-automatically&quot; data-footnote-ref=&quot;&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF[0]=100 # 문제 없음
ASDF[1]=200
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;대부분의 프로그래밍 언어에서는 배열을 먼저 만들어두어야 값을 추가할 수 있습니다. 파이썬이라는 프로그래밍 언어의 경우 다음과 같이 배열을 먼저 선언해야 합니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;asdf = []  # 배열 선언
asdf[0] = 100
asdf[1] = 200
asdf[2] = &quot;Hello&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;특이한-성질-순서대로-값이-존재하지-않아도-된다&quot;&gt;[특이한 성질] 순서대로 값이 존재하지 않아도 된다&lt;/h2&gt;
&lt;p&gt;배시는 다른 몇몇 프로그래밍 언어와 달리 배열에 값을 추가할 때 인덱스 0부터 연속적으로 값을 채워나가지 않아도 됩니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-nor-contiguously&quot; id=&quot;fnref-nor-contiguously&quot; data-footnote-ref=&quot;&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;. 인덱스 0, 인덱스 1, 인덱스 2같이 연속적으로 채우지 않고 인덱스 0, 인덱스 5, 인덱스 123같이 불연속적으로 채울 수도 있습니다.&lt;/p&gt;
&lt;p&gt;다음은 인덱스 12345에 &lt;code&gt;99999&lt;/code&gt;를 추가하는 코드입니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF=(100 200 300)
ASDF[12345]=99999
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;특이한-성질-인덱스-명시-배열-생성&quot;&gt;[특이한 성질] 인덱스 명시 배열 생성&lt;/h2&gt;
&lt;p&gt;배열을 생성할 때 &lt;code&gt;배열이름=([인덱스]=값 [인덱스]=값)&lt;/code&gt; 형태로 인덱스를 지정하여 생성하는 것도 가능합니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-subscript-is-supplied&quot; id=&quot;fnref-subscript-is-supplied&quot; data-footnote-ref=&quot;&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF=([10]=100 [0]=200 [2]=300)
&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;markdown-alert markdown-alert-note&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;code&gt;(값1 [인덱스]=값2 값3)&lt;/code&gt;처럼 인덱스를 지정하는 것과 지정하지 않는 것을 혼용할 수도 있습니다.&lt;/p&gt;
&lt;p&gt;인덱스를 명시하지 않을 경우의 규칙은 언제나 &lt;strong&gt;왼쪽보다 1 더 큰 인덱스&lt;/strong&gt;입니다. 다음 코드를 보세요:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;# [3]=Global [4]=World
ASDF=([10]=Welcome [2]=Hello Global World [50]=Bye)
echo ${ASDF[10]}
echo ${ASDF[2]}
echo ${ASDF[3]}
echo ${ASDF[4]}
echo ${ASDF[50]}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Global&lt;/code&gt;은 &lt;code&gt;[2]=Hello&lt;/code&gt;의 왼쪽에 있으므로 인덱스 3에 할당됩니다. &lt;code&gt;World&lt;/code&gt;는 &lt;code&gt;Global&lt;/code&gt;의 인덱스보다 1 더 큰 인덱스 4에 할당됩니다.&lt;/p&gt;
&lt;p&gt;실행 결과:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;Welcome
Hello
Global
World
Bye
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id=&quot;배열-끝-값-추가&quot;&gt;배열 끝 값 추가&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;배열이름+=(값1 값2 값3)&lt;/code&gt; 형태로 배열에 값을 추가합니다.&lt;/p&gt;
&lt;p&gt;다음은 배열을 생성한 뒤 배열 끝에 값을 추가하는 코드입니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF=(Alpha Beta Theta Gamma)
ASDF+=(123)
ASDF+=(456 789)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;123&lt;/code&gt;과 &lt;code&gt;456&lt;/code&gt;, &lt;code&gt;789&lt;/code&gt;를 추가했습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;단 하나의 값&lt;/strong&gt;을 추가한다고 해도 반드시 괄호를 붙여야 합니다. 다음 코드를 보세요:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF=(Alpha Beta Theta Gamma)
ASDF+=123 # 잘못됨!

echo ${ASDF[0]}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;배시의 인덱스 없이 배열 이름만으로 배열에 접근하려 하면 배열의 첫 번째 값처럼 해석하는 성질로 인해 &lt;code&gt;ASDF+=123&lt;/code&gt;은 &lt;code&gt;ASDF[0]+=123&lt;/code&gt;같이 해석됩니다. &lt;code&gt;+=&lt;/code&gt;을 배열이 아닌 변수에 사용하면 문자열을 붙이는 방식으로 동작합니다.&lt;/p&gt;
&lt;p&gt;실행 결과:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;Alpha123
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;ASDF[0]&lt;/code&gt;에 존재하는 &lt;code&gt;Alpha&lt;/code&gt;와 &lt;code&gt;123&lt;/code&gt;이 붙어 &lt;code&gt;Alpha123&lt;/code&gt;이라는 결과가 나왔습니다.&lt;/p&gt;
&lt;h2 id=&quot;배열-합치기&quot;&gt;배열 합치기&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;${ASDF[@]}&lt;/code&gt;를 응용해 두 개의 배열을 하나로 합치는(결합하는) 데 사용할 수도 있습니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;AAA=(123 456 789)
BBB=(1 4 7)

CCC=(${AAA[@]} ${BBB[@]})

echo ${CCC[@]}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;출력 결과:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;123 456 789 1 4 7
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;앞서 말씀드렸듯 &lt;strong&gt;배열의 값이 공백을 포함할 수도 있다면&lt;/strong&gt; &lt;code&gt;${변수이름[@]}&lt;/code&gt; 대신 큰따옴표가 들어간 &lt;code&gt;&quot;${변수이름[@]}&quot;&lt;/code&gt;를 사용해야 합니다. 그렇지 않을 경우 여러 공백을 하나로 묶는 배시의 성질로 인해 공백이 모두 무시되며 여러 가지 예기치 않은 결과가 일어날 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;markdown-alert markdown-alert-note&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Note&lt;/p&gt;
&lt;p&gt;배시는 개별적으로 취급하는 문자열과 문자열 사이의 공백을 하나로 합치는 성질이 있습니다. 이 성질에 관해서는...&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;다음은 배열의 값이 공백을 포함함에도 불구하고 &lt;code&gt;${변수이름[@]}&lt;/code&gt;을 사용한 잘못된 코드입니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;AAA=(&quot;1   1&quot; &quot;2   2&quot;)
BBB=(&quot;b   b&quot; &quot;B   B&quot;)

CCC=(${AAA[@]} ${BBB[@]}) # 잘못됨!

echo ${CCC[@]} # 잘못됨!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;출력 결과:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1 1 2 2 b b B B
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;여러 공백을 하나로 묶는 배시의 성질로 인해 공백이 모두 무시된 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;다음은 공백을 포함하는 값을 가진 배열에 대해, 제대로 &lt;code&gt;&quot;${변수이름[@]}&quot;&lt;/code&gt;을 사용한 코드입니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;AAA=(&quot;1   1&quot; &quot;2   2&quot;)
BBB=(&quot;b   b&quot; &quot;B   B&quot;)

CCC=(&quot;${AAA[@]}&quot; &quot;${BBB[@]}&quot;)

echo &quot;${CCC[@]}&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;출력 결과:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1   1 2   2 b   b B   B
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;예상 대로 공백이 출력됨을 확인할 수 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;배열-크기-얻기&quot;&gt;배열 크기 얻기&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;${#변수이름[@]}&lt;/code&gt; (&lt;code&gt;변수이름&lt;/code&gt; 앞에 &lt;code&gt;#&lt;/code&gt;이 있습니다) 형태로 배열에 들어 있는 값의 개수를 구합니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-length-of-array&quot; id=&quot;fnref-length-of-array&quot; data-footnote-ref=&quot;&quot;&gt;9&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF=(123 456 789)
ZXCV=(A B C D E F G)

echo ${#ASDF[@]}
echo ${#ZXCV[@]}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;실행 결과:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;3
7
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;배열의 크기는 시작 인덱스부터 마지막 인덱스까지의 길이를 구하는 것이 &lt;strong&gt;아닙니다.&lt;/strong&gt; 순전히 배열에 들어 있는 값의 개수를 구합니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF=(123 456 [100]=789)

echo ${#ASDF[@]}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;실행 결과:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;시작 인덱스부터 마지막 인덱스까지의 길이를 구하는 것이었다면 &lt;code&gt;100&lt;/code&gt;을 출력해야 합니다. &lt;code&gt;3&lt;/code&gt;을 출력하는 것으로 보아 배열에 들어있는 값의 개수를 구한다는 것을 알 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;markdown-alert markdown-alert-note&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;code&gt;${#변수이름[1]}&lt;/code&gt;과 같이 길이를 구할 때 &lt;code&gt;@&lt;/code&gt; 대신 인덱스를 넣을 경우, 배열에 존재하는 값의 개수를 구하는 게 아니라 해당 값의 문자열 길이를 얻습니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF=(Short LongLongLong &quot;  &quot;)
echo ${#ASDF[0]}
echo ${#ASDF[1]}
echo ${#ASDF[2]}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;실행 결과:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;5
12
2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Short&lt;/code&gt;는 5글자, &lt;code&gt;LongLongLong&lt;/code&gt;은 12글자, &lt;code&gt;&quot;  &quot;&lt;/code&gt;은 2글자이므로 각각 &lt;code&gt;5&lt;/code&gt;, &lt;code&gt;12&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt;가 출력되었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;배열-전체-인덱스-얻기&quot;&gt;배열 전체 인덱스 얻기&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;${!변수이름[@]}&lt;/code&gt; (&lt;code&gt;변수이름&lt;/code&gt; 앞에 &lt;code&gt;!&lt;/code&gt;가 있습니다) 형태로 배열이 가진 전체 인덱스 목록을 얻을 수 있습니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-obtain-the-keys&quot; id=&quot;fnref-obtain-the-keys&quot; data-footnote-ref=&quot;&quot;&gt;10&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF=(123 456 789 [777]=TripleSeven)
echo ${!ASDF[@]}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;출력 결과:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 1 2 777
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;배열-순회&quot;&gt;배열 순회&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;for&lt;/code&gt; 명령어를 통해 배열의 값 하나 하나에 동일한 연산을 수행할 수 있습니다. 값을 대량으로 변경하거나 모든 값을 출력할 때 사용합니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF=(111 222 333)
for V in &quot;${ASDF[@]}&quot;
do
    echo $V
done
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;출력 결과:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;111
222
333
&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;markdown-alert markdown-alert-note&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;code&gt;for&lt;/code&gt; 명령어에 관한 자세한 내용은...&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;값-제거&quot;&gt;값 제거&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;unset&lt;/code&gt; 명령어를 통해 배열의 값을 제거할 수 있습니다. &lt;code&gt;unset 변수이름[0]&lt;/code&gt;, &lt;code&gt;unset 변수이름[1]&lt;/code&gt; 형태입니다. &lt;code&gt;unset 변수이름&lt;/code&gt; 형태로 배열 전체를 제거할 수도 있습니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-unset&quot; id=&quot;fnref-unset&quot; data-footnote-ref=&quot;&quot;&gt;11&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;다음 코드는 배열의 값을 하나 제거합니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;A[5]=123
unset A[5]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;다음 코드는 배열 전체를 제거합니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;A=(123 456 789)
unset A
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;값-제거-vs-빈-문자열-대입&quot;&gt;값 제거 vs 빈 문자열 대입&lt;/h3&gt;
&lt;p&gt;배시는 배열에 빈 문자열(길이가 0인 문자열)이 들어가는 것을 정상적인 값의 설정으로 취급합니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-null-string&quot; id=&quot;fnref-null-string&quot; data-footnote-ref=&quot;&quot;&gt;12&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF=(123 456 789)
ASDF[2]= # 빈 문자열 대입
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;그러므로 빈 문자열을 대입하는 것은 배열에 있는 값을 &lt;strong&gt;제거&lt;/strong&gt;하는 게 아니라 그저 빈 문자열로 덮어쓸 뿐입니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF=(123 456 789)
echo &quot;Count:&quot; ${#ASDF[@]}
echo &quot;Get all:&quot; ${ASDF[@]}
ASDF[1]=
echo &quot;Count:&quot; ${#ASDF[@]}
echo &quot;Get all:&quot; ${ASDF[@]}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;출력 결과:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Count: 3
Get all: 123 456 789
Count: 3
Get all: 123  789
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;값이 제거되지 않고 그대로 남아있는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;음수-인덱스&quot;&gt;음수 인덱스&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;ASDF[-1]&lt;/code&gt;과 같이 인덱스 자리에 음수를 사용하면 배열이 가진 마지막 인덱스에서부터 거꾸로 접근합니다. &lt;code&gt;ASDF[-1]&lt;/code&gt;이 마지막 인덱스입니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-negative-number&quot; id=&quot;fnref-negative-number&quot; data-footnote-ref=&quot;&quot;&gt;13&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF=(100 200 300)
echo ${ASDF[-1]} # ASDF[2]와 같음
echo ${ASDF[-2]} # ASDF[1]과 같음
echo ${ASDF[-3]} # ASDF[0]과 같음
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;출력 결과:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;300
200
100
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;음수 인덱스는 가장 마지막 인덱스부터 거꾸로 접근하기 때문에, 값이 들어있지 않은 인덱스는 아무런 값도 출력하지 않습니다.&lt;/p&gt;
&lt;p&gt;다음은 인덱스 9부터 거꾸로 값들을 출력하는 코드입니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;ASDF=(100 200 300)
ASDF[9]=1000
echo ${ASDF[-1]} # ASDF[9]와 같음
echo ${ASDF[-2]} # ASDF[8]과 같음
echo ${ASDF[-3]} # ASDF[7]과 같음
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;출력 결과:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1000


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;보시는 바와 같이 &lt;code&gt;${ASDF[-2]}&lt;/code&gt;, &lt;code&gt;${ASDF[-3]}&lt;/code&gt;은 아무 것도 출력되지 않은 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;특이한-성질-배열-이름-자체로-접근&quot;&gt;[특이한 성질] 배열 이름 자체로 접근&lt;/h2&gt;
&lt;p&gt;배시에서는 인덱스 없이 배열 이름만으로 배열에 접근하려 하면 &lt;strong&gt;배열의 첫 번째 값처럼 취급합니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-without-a-subscript&quot; id=&quot;fnref-without-a-subscript&quot; data-footnote-ref=&quot;&quot;&gt;14&lt;/a&gt;&lt;/sup&gt;.&lt;/strong&gt; &lt;code&gt;ASDF=100&lt;/code&gt;을 &lt;code&gt;ASDF[0]=100&lt;/code&gt;처럼 처리한다는 소리죠.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;입력 코드&lt;/th&gt;
&lt;th&gt;처리 코드&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ASDF=100&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ASDF[0]=100&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;echo ${ASDF}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;echo ${ASDF[0]}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ASDF=100&lt;/code&gt;&lt;br&gt;&lt;code&gt;ASDF[1]=200&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ASDF[0]=100&lt;/code&gt;&lt;br&gt;&lt;code&gt;ASDF[1]=200&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;배열의 값을 수정할 때, 배열의 값을 출력할 때 모두 적용됩니다. 심지어는 배열이 아직 생성되지 않았을 때의 값 또한 배열의 첫 번째 값처럼 취급합니다.&lt;/p&gt;
&lt;h2 id=&quot;특이한-성질-명시적-선언&quot;&gt;[특이한 성질] 명시적 선언&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;declare&lt;/code&gt; 명령어와 &lt;code&gt;-a&lt;/code&gt; 옵션을 통해 특정 변수를 배열로 선언할 수 있습니다. 이를 &lt;strong&gt;명시적 선언&lt;/strong&gt;이라 합니다. &lt;code&gt;-a&lt;/code&gt;는 &quot;A&quot;rray의 &quot;A&quot;에서 따왔습니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;declare -a ASDF
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;# 선언과 동시에 초기화도 가능
declare -a QWER=(100 200 300)
&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;markdown-alert markdown-alert-note&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Note&lt;/p&gt;
&lt;p&gt;명시적으로 배열을 선언하면 컴퓨터로 하여금 해당 변수를 최적화할 수 있는 여지를 줍니다. 이로 인해 속도가 향상될 수도 있습니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-may-speed-up&quot; id=&quot;fnref-may-speed-up&quot; data-footnote-ref=&quot;&quot;&gt;15&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;연관-배열-인덱스-배열-키&quot;&gt;연관 배열, 인덱스 배열, 키&lt;/h2&gt;
&lt;p&gt;2009년 출시된 배시 4.0부터 &lt;strong&gt;연관 배열&lt;/strong&gt;(associative array)이라는 새로운 문법이 추가되었습니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-new-goodies&quot; id=&quot;fnref-new-goodies&quot; data-footnote-ref=&quot;&quot;&gt;16&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;기존 배열과 달리, 연관 배열에는 인덱스가 들어갈 자리에 &lt;strong&gt;문자열&lt;/strong&gt;이 들어갑니다. 이 문자열을 가리켜 &lt;strong&gt;키&lt;/strong&gt;라고 합니다.&lt;/p&gt;
&lt;p&gt;기존의 인덱스를 사용하던 배열은 연관 배열과 구분할 필요가 있으므로 따로 &lt;strong&gt;인덱스 배열&lt;/strong&gt;(indexed array)이라고 부릅니다.&lt;/p&gt;
&lt;h2 id=&quot;인덱스-배열-vs-연관-배열&quot;&gt;인덱스 배열 vs 연관 배열&lt;/h2&gt;
&lt;p&gt;연관 배열의 기본적인 동작 방식은 인덱스 배열과 매우 유사합니다. 다음은 인덱스 배열과 연관 배열에서 제공하는 기능을 비교하는 표입니다:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;변경&lt;/th&gt;
&lt;th&gt;얻기&lt;/th&gt;
&lt;th&gt;전체 얻기&lt;/th&gt;
&lt;th&gt;배열 크기&lt;/th&gt;
&lt;th&gt;제거&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;인덱스 배열&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ASDF[3]=Hello&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;${ASDF[3]}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;${ASDF[@]}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;${#ASDF[@]}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;unset ASDF[3]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;연관 배열&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ASDF[greeting]=Hello&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;${ASDF[greeting]}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;${ASDF[@]}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;${#ASDF[@]}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;unset ASDF[greeting]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;다만 연관 배열은 인덱스 배열과는 다른 두 가지 차이점이 존재합니다:&lt;/p&gt;
&lt;h3 id=&quot;명시적-선언-필수&quot;&gt;명시적 선언 필수&lt;/h3&gt;
&lt;p&gt;연관 배열과 인덱스 배열에는 한 가지 중요한 차이점이 있습니다. 명시적 선언을 해도 되고 안 해도 되는 인덱스 배열과 달리, 연관 배열을 사용하기 위해서는 반드시 &lt;strong&gt;명시적으로 선언&lt;/strong&gt;해야만 합니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-the-subscript-is-required&quot; id=&quot;fnref-the-subscript-is-required&quot; data-footnote-ref=&quot;&quot;&gt;17&lt;/a&gt;&lt;/sup&gt;. 다음과 같이 선언합니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;declare -A 변수이름
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;연관 배열 역시 인데스 배열처럼 배열 생성과 함께 값을 추가할 수 있습니다. 다만 인덱스 배열과 달리 &lt;strong&gt;키를 자동으로 지정해주지 않습니다.&lt;/strong&gt; 그러므로 다음과 같이 언제나 키를 명시해야 합니다 (앞서 설명한 &#39;인덱스 배열을 생성하면서 인덱스를 명시하는 방법&#39;과 동일한 형태입니다):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;declare -A 변수이름=([키]=값 [키]=값 [키]=값)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;키를 지정하지 않으면 오류가 발생합니다.&lt;/p&gt;
&lt;p&gt;다음은 연관 배열을 생성하면서 키를 명시하지 않는 잘못된 코드입니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;declare -A ASDF=(123 456 789) # 잘못됨!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;출력 결과:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-bash: ASDF: 123: must use subscript when assigning associative array
-bash: ASDF: 456: must use subscript when assigning associative array
-bash: ASDF: 789: must use subscript when assigning associative array
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;예상대로 오류가 발생한 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;h3 id=&quot;키에는-순서가-없다&quot;&gt;키에는 순서가 없다&lt;/h3&gt;
&lt;p&gt;인덱스 배열의 인덱스와 달리, 연관 배열의 키에는 &lt;strong&gt;순서가 없습니다.&lt;/strong&gt; 그렇기 때문에 전체 값을 얻을 때에도 어떤 순서로 얻게 될지 알 수 없습니다.&lt;/p&gt;
&lt;p&gt;다음은 연관 배열의 키에 순서가 없음을 확인하는 코드입니다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;declare -A ASDF=([aaa]=111 [bbb]=222 [ccc]=333 [ddd]=444 [eee]=555)
echo ${ASDF[@]}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;출력 결과:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;111 555 333 222 444
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;연관 배열의 키에는 순서가 없으므로 출력 결과는 실행 환경마다 다를 수 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;2차원-배열&quot;&gt;2차원 배열&lt;/h2&gt;
&lt;p&gt;배시는 공식적으로 1차원 배열만을 지원합니다&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-one-dimensional&quot; id=&quot;fnref-one-dimensional&quot; data-footnote-ref=&quot;&quot;&gt;18&lt;/a&gt;&lt;/sup&gt;. 2차원 배열을 위한 문법은 제공하지 않습니다.&lt;/p&gt;
&lt;h2 id=&quot;참고&quot;&gt;참고&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Arrays.html&quot;&gt;Arrays - Bash Reference Manual&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tldp.org/LDP/abs/html/arrays.html&quot;&gt;Arrays - Advanced Bash-Scripting Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section class=&quot;footnotes&quot; data-footnotes=&quot;&quot;&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-way-1&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Arrays.html&quot;&gt;Arrays - Bash Reference Manual&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Arrays are assigned to using compound assignments of the form&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;name=(value1 value2 … )
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-way-1&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;1&quot; aria-label=&quot;Back to reference 1&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-starts-at-zero&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Arrays.html&quot;&gt;Arrays - Bash Reference Manual&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Indexing starts at zero.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-starts-at-zero&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;2&quot; aria-label=&quot;Back to reference 2&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-braces-are-required&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Arrays.html&quot;&gt;Arrays - Bash Reference Manual&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The braces are required to avoid conflicts with the shell’s filename expansion operators.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-braces-are-required&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;3&quot; aria-label=&quot;Back to reference 3&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-at-or-asterisk&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Arrays.html&quot;&gt;Arrays - Bash Reference Manual&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If the subscript is ‘@’ or ‘&lt;em&gt;’, the word expands to all members of the array name. These subscripts differ only when the word appears within double quotes. If the word is double-quoted, ${name[&lt;/em&gt;]} expands to a single word with the value of each array member separated by the first character of the IFS variable, and ${name[@]} expands each element of name to a separate word. When there are no array members, ${name[@]} expands to nothing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-at-or-asterisk&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;4&quot; aria-label=&quot;Back to reference 4&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-way-2&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Arrays.html&quot;&gt;Arrays - Bash Reference Manual&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;each value is of the form &lt;code&gt;[subscript]=string&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-way-2&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;5&quot; aria-label=&quot;Back to reference 5&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-created-automatically&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Arrays.html&quot;&gt;Arrays - Bash Reference Manual&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An indexed array is created automatically if any variable is assigned to using the syntax&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name[subscript]=value
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-created-automatically&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;6&quot; aria-label=&quot;Back to reference 6&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-nor-contiguously&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Arrays.html&quot;&gt;Arrays - Bash Reference Manual&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;nor any requirement that members be indexed or assigned contiguously.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-nor-contiguously&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;7&quot; aria-label=&quot;Back to reference 7&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-subscript-is-supplied&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Arrays.html&quot;&gt;Arrays - Bash Reference Manual&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;where each value is of the form [subscript]=string. ... if the optional subscript is supplied, that index is assigned to;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-subscript-is-supplied&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;8&quot; aria-label=&quot;Back to reference 8&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-length-of-array&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Arrays.html&quot;&gt;Arrays - Bash Reference Manual&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;${#name[subscript]} expands to the length of ${name[subscript]}. If subscript is ‘@’ or ‘*’, the expansion is the number of elements in the array.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-length-of-array&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;9&quot; aria-label=&quot;Back to reference 9&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-obtain-the-keys&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Arrays.html&quot;&gt;Arrays - Bash Reference Manual&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It is possible to obtain the keys (indices) of an array as well as the values. ${!name[@]} and ${!name[*]} expand to the indices assigned in array variable name. The treatment when in double quotes is similar to the expansion of the special parameters ‘@’ and ‘*’ within double quotes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-obtain-the-keys&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;10&quot; aria-label=&quot;Back to reference 10&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-unset&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Arrays.html&quot;&gt;Arrays - Bash Reference Manual&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The unset builtin is used to destroy arrays. &lt;code&gt;unset name[subscript]&lt;/code&gt; destroys the array element at index subscript. Negative subscripts to indexed arrays are interpreted as described above. Unsetting the last element of an array variable does not unset the variable. &lt;code&gt;unset name&lt;/code&gt;, where name is an array, removes the entire array.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-unset&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;11&quot; aria-label=&quot;Back to reference 11&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-null-string&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Arrays.html&quot;&gt;Arrays - Bash Reference Manual&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The null string is a valid value.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-null-string&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;12&quot; aria-label=&quot;Back to reference 12&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-negative-number&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Arrays.html&quot;&gt;Arrays - Bash Reference Manual&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When assigning to an indexed array, if name is subscripted by a negative number, that number is interpreted as relative to one greater than the maximum index of name, so negative indices count back from the end of the array, and an index of -1 references the last element.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-negative-number&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;13&quot; aria-label=&quot;Back to reference 13&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-without-a-subscript&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Arrays.html&quot;&gt;Arrays - Bash Reference Manual&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Referencing an array variable without a subscript is equivalent to referencing with a subscript of 0.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-without-a-subscript&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;14&quot; aria-label=&quot;Back to reference 14&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-may-speed-up&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://tldp.org/LDP/abs/html/arrays.html&quot;&gt;Arrays - Advanced Bash-Scripting Guide&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Adding a superfluous declare -a statement to an array declaration may speed up execution of subsequent operations on the array.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-may-speed-up&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;15&quot; aria-label=&quot;Back to reference 15&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-new-goodies&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://tldp.org/LDP/abs/html/bashver4.html&quot;&gt;Bash, version 4 - Advanced Bash-Scripting Guide&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Chet Ramey announced Version 4 of Bash on the 20th of February, 2009.
Among the new goodies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Associative arrays.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-new-goodies&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;16&quot; aria-label=&quot;Back to reference 16&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-the-subscript-is-required&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Arrays.html&quot;&gt;Arrays - Bash Reference Manual&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When assigning to an associative array, the subscript is required.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-the-subscript-is-required&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;17&quot; aria-label=&quot;Back to reference 17&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-one-dimensional&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Arrays.html&quot;&gt;Arrays - Bash Reference Manual&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Bash provides one-dimensional indexed and associative array variables.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a href=&quot;#fnref-one-dimensional&quot; class=&quot;footnote-backref&quot; data-footnote-backref=&quot;&quot; data-footnote-backref-idx=&quot;18&quot; aria-label=&quot;Back to reference 18&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
      <category>linux</category>
      <pubDate>Sat, 02 May 2020 00:00:00 GMT</pubDate>
      <guid>https://www.bangseongbeom.com/bash-arrays</guid>
      
    </item>
    
  </channel>
</rss>
