반응형

minicom 설치 후 시리얼 장치에 대한 읽기 동작은 정상 동작하지만,
쓰기 동작이 안되는 경우

이미 minicom 이 실행 중인 경우 
1. Ctrl + A 누른 후 이어서 (Ctrl은 떼고) Z 를 누른다
2. 무언가 창이 뜨면 O (cOnfigure Mimicom)를 누른다.


3. Serial port setup 을 들어간다


4. Hardware Flow Control을 Yes -> No로 변경한다. (F에 해당하면 F를 한번 더 누르면 토글된다)


5. No로 변경된 것을 확인 후 엔터 입력한다
6. Save setup as dfl 을 눌러서 해당 설정을 기본값으로 설정한다.


7. Exit 

정상적으로 동작 됨을 확인할 수 있다.

minicom 실행 전인 경우
1. sudo minicom -s 를 입력한다.
위의 3번부터 따라서 실행한다. 

반응형

'Spadeworks > bash' 카테고리의 다른 글

[bash] 파일 크기 순으로 검색  (0) 2023.12.12
[bash] 명령어 반복  (0) 2023.09.19
[bash] 파일 탐색  (0) 2023.09.10
[bash] bash를 이용한 json 파일 파싱  (0) 2022.08.11
[bash] 특정 길이의 무작위 문자열 획득  (0) 2022.08.11
반응형
개발 중에 귀찮은 일들을 스크립트로 만들어두고 공유하려는 목적입니다.
만약 더 좋은 방법을 알고 계신다면면 댓글 달아주세요 !

 

script

import subprocess
from concurrent.futures import ThreadPoolExecutor
import argparse
import ipaddress
import os
import time

# Function to clear the console
def clear_console():
    # Use 'cls' for Windows and 'clear' for Unix-like systems
    os.system('cls' if os.name == 'nt' else 'clear')

# Function to ping an IP address
def ping_ip(ip):
    result = subprocess.run(['ping', '-c', '1', '-W', '0.5', ip], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    if result.returncode == 0:
        return ip
    return None

# Function to ping multiple IPs and return the alive ones
def ping_ips(ips):
    alive_ips = []
    with ThreadPoolExecutor(max_workers=100) as executor:
        results = executor.map(ping_ip, ips)
    
    for ip in results:
        if ip:
            alive_ips.append(ip)
    
    return alive_ips

# Function to format the output
def format_output(start_ip, end_ip, alive_ips):
    clear_console()  # Clear the console before printing
    print(f"Scanning Range\n{start_ip} ~ {end_ip}")
    
    if alive_ips:
        print("\nAlive")
        for ip in alive_ips:
            print(f"- {ip}")
    else:
        print("\nAlive\n- None")

# Function to generate IP range from start to end IP
def generate_ip_range(start_ip, end_ip):
    start = ipaddress.IPv4Address(start_ip)
    end = ipaddress.IPv4Address(end_ip)
    return [str(ipaddress.IPv4Address(ip)) for ip in range(int(start), int(end) + 1)]

# Main function
def main():
    parser = argparse.ArgumentParser(description="Ping IP addresses within a specified range.")
    parser.add_argument('--start', required=True, help="Start IP address")
    parser.add_argument('--end', required=True, help="End IP address")
    parser.add_argument('-r', '--repeat', action='store_true', help="Repeat indefinitely until stopped")
    args = parser.parse_args()

    ips = generate_ip_range(args.start, args.end)

    try:
        if args.repeat:
            # Infinite loop until stopped manually (e.g., with Ctrl+C)
            while True:
                alive_ips = ping_ips(ips)
                format_output(args.start, args.end, alive_ips)
                time.sleep(1)  # Optional: Add a short delay between repetitions if needed
        else:
            # Single execution
            alive_ips = ping_ips(ips)
            format_output(args.start, args.end, alive_ips)
    except KeyboardInterrupt:
        print("\nExecution stopped by user. Exiting gracefully...")

if __name__ == "__main__":
    main()

 

example (w/o repeat)

  • start : 시작 IP
  • end : 끝 IP
  • repeat : 반복 여부 (마지막에 --repeat을 추가)

생각해보니 이 스크립트는 IP의 가장 마지막 자리만 변경해가면서 scan하고 있네요.
따라서 처음의 AAA.BBB.CCC 는 동일해야 하고, 만약 이 AAA,BBB,CCC가 다른 경우에 대해서는 고려되어있지 않습니다.

python3 scan.py --start 192.168.13.100 --end 192.168.13.150 

Scanning Range
192.168.13.100 ~ 192.168.13.255

Alive
- 192.168.13.101
- 192.168.13.105
- 192.168.13.126​

 

 

스크립트 작성 배경

 

여러 디바이스들의 상호작용이 필요한 분산 시스템을 개발하는 경우,
각 디바이스의 네트워크 상태가 정상인지 확인하는 것은 아주 중요한 일이다.

한쪽의 시스템을 완벽히 구성하고 전부 정상적으로 동작중이더라도,

어느 한쪽의 디바이스가 정상적으로 동작하지 못하면

테스트 결과가 이상하던지 아니면 테스트 자체가 불가능할 수도 있다.

 

최근 진행 중인 프로젝트에서는 어떤 SoC를 쓰냐, 시스템을 어떻게 구성하느냐에 따라 디바이스의 네트워크가 불능에 빠지는 경우를 꽤 자주 보게 되기도 하는데, 이로 인해 시간을 낭비하게 되는 경우가 많았다.

아직은 이 프로젝트의 진척이나 시스템의 성숙도가 낮아서 번거롭지만 이러한 fault들을 직접 모니터링해야 하는 필요성이 생겼고 간단하게 스크립트를 만들어 사용하게 되었다.

 

 

반응형
반응형

개발을 하다 보면 큰 파일들을 다루게 될 때가 종종 있다.
임베디드 개발을 예로 들자면 타겟의 루트 파일 시스템을 직접 flashing 해야 하거나
어느 때는 아주 큰 용량의 core 파일이나 로그 파일을 확인해야 할 때도 있다.

평소에 파일 관리를 잘하고 꼼꼼한 사람들은 안 그러겠지만,
나 처럼 즉흥적으로 처리하는 걸 좋아하거나 여기저기 다른 부서, 고객들로부터 다양한 이슈를 전달 받거나 하다 보면 
어느 순간 부족한 용량으로 인해 당황하게 될 때가 있다.

그럴 때 어디에 뭐가 있는지 찾는 일은 아주 성가시고 번거로운 일인데,
그래서 급하게 하나 만들었다.

큰 파일을 찾는 bash script.
find 기반으로 동작하며 꽤 쓸만하여 공유한다.
사실 한줄 짜리고 find 명령어에 능숙한 사람이라면 크게 의미 없지만 파라미터를 받아서 편하게 쓸 수 있는 장점이 있다...;

언제나 그렇듯 서두가 길었고, 스크립트는 다음과 같다.

#!/bin/bash

MIN_SIZE=${1:-800M}

ROOT_PATH=${2:-/}

find "$ROOT_PATH" -type f -size +"$MIN_SIZE" -exec du -h {} + | sort -rh | head -n 30

 

사용법은 다음과 같다.

 

# 사용법
./${script_path} ${minimum_size} ${search_path}

# 예시
./find_large.sh 1000M /data

 


즉 파라미터로 특정 크기 이상의 파일을 찾기 위해, 파일 탐색을 위한 파일의 최소 사이즈를 넘겨준다.

이를 통해 해당 사이즈보다 큰 파일들만을 검색하게 된다.
그리고 다음 파라미터로 검색을 수행 할 경로를 써주면 된다.

 

급할 때 나름 유용하니 머리 한 편에 이런 글이 있었지 하고 나중에 써먹어보길 바란다.

반응형

'Spadeworks > bash' 카테고리의 다른 글

minicom 키보드 입력 안되는 경우  (0) 2024.09.24
[bash] 명령어 반복  (0) 2023.09.19
[bash] 파일 탐색  (0) 2023.09.10
[bash] bash를 이용한 json 파일 파싱  (0) 2022.08.11
[bash] 특정 길이의 무작위 문자열 획득  (0) 2022.08.11
반응형

개발을 하다보면 하루 종일 터미널에서 빠져나오지 못하고 열심히 아주 열심히 삽질을 하고 있는 자신을 마주할 때가 있다.
그러한 삽질을 대신 해줄 수 있는 스크립트를 하나 가져왔다.

파라미터로 실행하고자 하는 명령어와 반복 횟수, 실행 주기를 설정하면 그에 맞게 명령어를 반복해주는 스크립트이다.
뭐 cron을 쓸 수도 있을 것이고 watch를 쓸 수도 있겠지만 횟수까지 설정할 수는 없기에 나름 유용할 수 있다. 
(글을 쓰다보니 watch를 쓰는게 더 나을 것 같기도 하다..)

아래의 스크립트 이며 파라미터는 다음과 같다. 
$1 명령어
$2 반복 횟수
$3 interval (ms) 

 

- 사용법 :

$ ./repeat_command.sh "echo 'Hello World'" 5 500
#!/bin/bash

# 사용법을 표시하는 함수
function usage() {
    echo "Usage: $0 [command] [repeat count] [delay in milliseconds]"
    exit 1
}

# 파라미터가 3개가 아닌 경우 사용법 표시
if [ "$#" -ne 3 ]; then
    usage
fi

command_to_run=$1
repeat_count=$2
delay_milliseconds=$3

# 밀리세컨드를 초로 변환
delay_seconds=$(echo "scale=3; $delay_milliseconds/1000" | bc)

# 반복해서 명령어 실행
for (( i=1; i<=$repeat_count; i++ )); do
    eval "$command_to_run"
    sleep $delay_seconds
done



쓰다보니 watch와 다른게 뭔가 싶어 기능을 추가해보았다.
무려 4번째 파라미터..!
$4 검색하고자 하는 문자열.

이 네번째 파라미터는 앞서 반복해서 뭔가를 실행하고 그 결과로 출력되는 내용 중에 이 파라미터가 포함되어있다면 'output_시간.log' 파일을 생성한다.

- 사용법 :

./repeat_command.sh "echo 'Hello World'" 5 500 "Hello"
#!/bin/bash

# 사용법을 표시하는 함수
function usage() {
    echo "Usage: $0 [command] [repeat count] [delay in milliseconds] [search string]"
    exit 1
}

# 파라미터가 4개가 아닌 경우 사용법 표시
if [ "$#" -ne 4 ]; then
    usage
fi

command_to_run=$1
repeat_count=$2
delay_milliseconds=$3
search_string=$4

# 밀리세컨드를 초로 변환
delay_seconds=$(echo "scale=3; $delay_milliseconds/1000" | bc)

output_file="output_$(date +%Y%m%d%H%M%S).log"

# 반복해서 명령어 실행
for (( i=1; i<=$repeat_count; i++ )); do
    result=$(eval "$command_to_run")
    
    if echo "$result" | grep -q "$search_string"; then
        echo "$result"
        echo "$(date): $result" >> $output_file
    fi
    
    sleep $delay_seconds
done


멋지지 않은가 ? 
그냥 뭔가 삘 받아서 만들어둔 스크립트이니 이 세상 어딘가 이 스크립트가 필요한 사람이 있길 바라며..글을 마무리한다.

반응형
반응형

로그를 남기다보면, vector 내부의 모든 원소를 출력해야 하는 일이 생길 수 있다.
보통 이런 일은 주로 디버깅을 할 때 발생하긴 하지만 알아두면 로그 공해도 줄일 수 있고 나름 쓸모가 많기에 그 방법을 소개한다.

- standard out으로 바로 출력하는 방법

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

int main() {
    std::vector<float> vec = {1.2f, 3.4f, 5.6f, 7.8f};

    std::copy(vec.begin(), vec.end(), std::ostream_iterator<float>(std::cout, " "));
    std::cout << std::endl;

    return 0;
}



- stringstream에 담아 출력하는 방법 

#include <iostream>
#include <vector>
#include <sstream>
#include <algorithm>
#include <iterator>

int main() {
    std::vector<float> vec = {1.2f, 3.4f, 5.6f, 7.8f};
    std::stringstream ss;

    std::copy(vec.begin(), vec.end(), std::ostream_iterator<float>(ss, " "));

    std::string result = ss.str();
    std::cout << result << std::endl;

    return 0;
}

 

반응형
반응형

 

RSA의 공개키와 개인키를 XML 형식으로 생성하는 예제이다.

 

 

using System.Security.Cryptography;

public void CreateRSAKey() 
{
    using (RSA rsa = RSA.Create())
    {
        // 개인 키 추출
        RSAParameters privateKeyParameters = rsa.ExportParameters(true);

        // 개인 키를 TEXT 형식으로 출력
        rsa.ImportParameters(privateKeyParameters);
        string privateKeyText = rsa.ToXmlString(true);
        Console.WriteLine("\n개인 키:\n" + privateKeyText);

        // 공개 키 추출
        RSAParameters publicKeyParameters = rsa.ExportParameters(false);

        // 공개 키를 TEXT 형식으로 출력
        rsa.ImportParameters(publicKeyParameters);
        string publicKeyText = rsa.ToXmlString(false);
        Console.WriteLine("공개 키:\n" + publicKeyText);

    }
}

 

생성한 공개키를 이용해 암호화 하는 예제

public void Encrypt(string text)
{
	RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
    rsa.FromXmlString(publicKey);
    
    byte[] utf = (new UTF8Encoding()).GetBytes(text);
    
    byte[] encrypt = rsa.Encrypt(utf, false);
    
    string result = Convert.ToBase64String(encrypt);
}

 

생성한 개인키를 이용해 복호화 하는 예제

public void Decrypt(string text)
{
	RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
    rsa.FromXmlString(privateKey);
    
    byte[] base64 = Convert.FromBase64String(text);
    
    byte[] decrypt = rsa.Decrypt(base64, false);
    
    string dec = (new UTF8Encoding()).GetString(decrypt, 0, decrypt.Length);
        
    string result = dec;
}

 

반응형

'Spadeworks > C#' 카테고리의 다른 글

gRPC DateTime C# 예제  (0) 2023.09.14
C# Convert TimeSpan to DateTime  (0) 2023.09.14
반응형

1. .proto 파일에 "google/protobuf/timestamp.proto" 를 import 한다.

import "google/protobuf/timestamp.proto";

 

2. 파라미터 타입을 아래와같이 지정한다.

message TestRequest {
	google.protobuf.Timestamp dt = 1;
}

 

3. C# 클라이언트에서는 아래와같이 파라미터를 가공한다.

var request = new TestRequest() {
	dt = Timestamp.FromDateTime(DateTime.Now)
}

 

4. gRPC 서버에서는 파라미터를 아래와같이 가공한다.

DateTime dt2 = request.dt.ToDateTime();
반응형

'Spadeworks > C#' 카테고리의 다른 글

C# RSA 키 생성 예제  (0) 2023.09.14
C# Convert TimeSpan to DateTime  (0) 2023.09.14
반응형

DateTime을 Time Span으로 바꾸는 방법은 아래와 같다.

 

DateTime dt = DateTime.Now;

TimeSpan span = TimeSpan.FromTicks(dt.Ticks);



Console.WriteLine(span);

 

반대로, TimeSpan 값을 DateTime 으로 바꾸는 방법은 아래 두가지 방법이 있다.

 

DateTime dt2 = new DateTime() + span;
DateTime dt3 = new DateTime(span.Ticks);



Console.WriteLine(dt2);

Console.WriteLine(dt3);
반응형

'Spadeworks > C#' 카테고리의 다른 글

C# RSA 키 생성 예제  (0) 2023.09.14
gRPC DateTime C# 예제  (0) 2023.09.14
반응형

ubuntu 20.04를 사용하면서 처음 겪는 현상이 있었다.
마우스가 커서를 움직이는 것은 가능하나 (좌/우)클릭만 안되는 것이었다.

이문제를 해결하기 위해 구글링을 해보다가 다음과 같은 명령어를 통해 해결할 수 있었다.

sudo udevadm trigger

 

반응형
반응형

간단한 파일 탐색을 위한 스크립트를 작성해보았다.
막강한 명령어인 find를 기반으로 동작하고 몇가지 옵션을 간편하게 적용할 수 있도록 해둔 것으로 이해하면 좋을 것 같다.

사용은 아래와 같다. (script의 이름은 대충 finder라고 지어뒀으니 마음에 드는 이름으로 바꿔서 쓰시길)

./finder.sh 경로이름 -i include -i want -e exclude -e trash -f json -h -o result.txt

 

여러가지 옵션을 지원하는데 간단하게 설명해보자면

  • -i : include
    전체 경로에서 해당 키워드가 포함되는 라인만 출력 대상에 포함한다.
    해당 옵션은 복수 개를 사용할 수 있다.
    예를 들자면
    -i task -i net
    위와 같이 옵션을 설정한다면 경로 상 task 키워드와 net 키워드가 모두 포함된 줄을 출력 대상에 포함한다.

    (이 부분은 요구사항을 어떻게 정의하고 ux를 어떻게 제공할지에 따른 개발자 개인의 성향 차이가 있을 수 있다.
    여러 -i 옵션에 사용된 키워드 중 하나만 포함되도 출력되는 것을 원할 수도 있으나 원하는 파일을 찾는다는 기능에 집중해서 생각해보면 하나라도 포함되는 것을 출력하게 되면 그 결과가 집중되지 않고 발산될 수 있는 가능성이 있음을 알 수 있다. 따라서 모든 키워드가 포함되는것이 원하는 기능의 측면에서 더 적절할 것이라는 결론을 내릴 수 있었다.)
  • -e : exclude
    이 옵션은 말 그대로 제외하고자 하는 키워드를 설정하는 것이다.
    -i 옵션과 동일하게 복수개를 설정할 수 있지만 해당 옵션은 개별 적용이 됨을 이해해야 한다.
  • -h : 숨김 파일 포함
    해당 옵션을 명시적으로 설정하게 되면 숨김 파일을 출력 결과에 포함하게 된다. 기본값은 당연히 숨김 파일은 숨긴채로 결과를 출력한다.
  • -f : 출력 포맷 (json, plain)
    이 옵션은 많은 개선/발전이 필요하다. 솔직하게는 구색을 위해 끼워넣은 옵션이라고 보는 편이 좋다.
    각설하고 해당 옵션은 json 또는 plain 이라는 키워드를 값으로 받게 된다. plain은 find 를 해서 나온 결과와 동일하며 json은 결과물들을 json array 형태로 출력해준다. 계층적으로 표현해주기 위해서는 tree 명령어의 도움을 받을 수는 있으나 해당 패키지의 설치가 필요하기에 굳이 지원하지 않는 것으로 결정하였다. (해당 패키지 설치는 아주 쉬운 편이지만 본 블로그에서는 왠만해서는 그 어떤 의존성도 없는 스크립트들을 만들어볼 것이다.)
  • -o 결과물 저장
    출력 결과 내용을 파일로 저장하기 위한 옵션이다. 
#!/bin/bash

usage() {
  echo "Usage: $0 path [-i include]... [-e exclude]... [-o output] [-h] [-f format]"
  echo "Options:"
  echo "  path  The directory path to search in."
  echo "  -i    Include keyword in path (can be used multiple times)"
  echo "  -e    Exclude keyword from path (can be used multiple times)"
  echo "  -o    Output file path"
  echo "  -h    Search hidden files"
  echo "  -f    Output format: json or plain (default: plain)"
  exit 1
}

declare -a includes
declare -a excludes
output=""
hidden="false"
format="plain"

# Capture the search path first
path="$1"
shift

# If no path or it starts with '-', show usage
if [ -z "$path" ] || [[ "$path" == -* ]]; then
  usage
fi

while getopts "i:e:o:hf:" opt; do
  case $opt in
    i) includes+=("$OPTARG") ;;
    e) excludes+=("$OPTARG") ;;
    o) output="$OPTARG" ;;
    h) hidden="true" ;;
    f) format="$OPTARG" ;;
    \?) usage ;;
  esac
done

# Start constructing the find command
cmd="find '$path'"

# Handle hidden files
if [ "$hidden" != "true" ]; then
  cmd="$cmd ! -path '*/.*'"
fi

# Handle include keywords
if [ "${#includes[@]}" -gt 0 ]; then
  for keyword in "${includes[@]}"; do
    cmd="$cmd -path '*$keyword*'"
  done
fi

# Handle exclude keywords
for keyword in "${excludes[@]}"; do
  cmd="$cmd ! -path '*$keyword*'"
done

# Add the print command
cmd="$cmd -print"

# Handle format
case "$format" in
  json)
    cmd="$cmd | sed 's/^/\"/' | sed 's/$/\",/' | (echo '['; cat; echo ']')"
    ;;
  plain)
    ;; # Nothing to do here, as the default is to just print
  *)
    ;; # Default case: just print
esac

# Handle output
if [ -n "$output" ]; then
  cmd="$cmd > '$output'"
fi

eval "$cmd"

 

반응형

+ Recent posts